在本章中,你将学会使用TextEditor
多行文本实现一个多行文本输入框。
在iOS14
中,苹果为SwiftUI
框架引入了一个名为TextEditor
的多行文本框组件,TextEditor
文本框可以实现显示和编辑多行文本。
那么,本章我们就来了解下TextEditor
多行文本框的使用。
首先,创建一个新项目,命名为SwiftUITextEditor
。
TextEditor
多行文本框和TextField
输入框的使用方法很类似,需要定义变量绑定内容。
然后,我们也可以像TextField
输入框一样,给TextEditor
多行文本框添加修饰符美化它。
struct ContentView: View { @State private var message = "" var body: some View { TextEditor(text: $message) .font(.title) .lineSpacing(20) // 行距 .autocapitalization(.words) .disableAutocorrection(true) .padding() } }
如果我们要统计TextEditor
多行文本框的输入字数时,这里引用一个TextEditor
多行文本框的修饰符.onChange
改变时,我们可以通过.onChange
改变时的修饰符和Text
文本,来实现TextEditor
多行文本框字数的统计。
.onChange(of: message) { value in //代码块 }
我们先定义字数统计的初始值wordCount
。
@State private var wordCount: Int = 0
然后通过ZStack
叠加视图将TextEditor
多行文本框和Text
文本包裹在一起,我们把wordCount
字数统计放在右上角。
每当我们输入一个字符时,onChange
修饰符中的代码就会被调用。
在闭包中,我们计算message
中的单词总数,然后动态更新wordCount
字数统计。
struct ContentView: View { @State private var message = "" @State private var wordCount: Int = 0 var body: some View { ZStack(alignment: .topTrailing) { // 多行文本框 TextEditor(text: $message) .font(.title) .lineSpacing(20) .autocapitalization(.words) .disableAutocorrection(true) .padding() //改变时 .onChange(of: message) { _ in let words = message.split { $0 == " " || $0.isNewline } self.wordCount = words.count } // 字数统计 Text("\(wordCount)") .font(.headline) .foregroundColor(.secondary) .padding(.trailing) } } }
样式我们再美化一下,使用.overlay
加个圆角边框。
.overlay( RoundedRectangle(cornerRadius: 8) .stroke(Color.gray, lineWidth: 1) )
嗯,不错。
不过可惜的一点是,TextEditor
多行文本框不像TextField
输入框一样,可以直接加上placehoder
注释文字,这需要我们自己实现。
也不难,我们可以通过判断message
输入文字是否为空,或者wordCount
字数统计是否为0
来实现没有输入内容时显示placehoder
注释文字。
完整代码如下:
struct ContentView: View { @State private var message = "" @State private var wordCount: Int = 0 var body: some View { ZStack(alignment: .topLeading) { ZStack(alignment: .bottomTrailing) { // 多行文本框 TextEditor(text: $message) .font(.title3) .lineSpacing(20) .autocapitalization(.words) .disableAutocorrection(true) .padding() .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 180) // 改变时 .onChange(of: message) { _ in let words = message.split { $0 == " " || $0.isNewline } self.wordCount = words.count } // 字数统计 Text("\(wordCount)") .font(.headline) .foregroundColor(.secondary) .padding(.trailing) .padding() } //边框 .overlay( RoundedRectangle(cornerRadius: 8) .stroke(Color.gray, lineWidth: 1) ) // 注释文字 if message.isEmpty { Text("请输入内容") .foregroundColor(Color(UIColor.placeholderText)) .padding(15) } } .padding() } }
快来动手试试吧!