
目录
[单行输入和密码输入 TextField SecureField](#单行输入和密码输入 TextField SecureField)
[双向绑定 变量](#双向绑定 变量)
[预设格式 textFieldStyle](#预设格式 textFieldStyle)
[内容类型 textContentType](#内容类型 textContentType)
[设置键盘类型 keyboardType](#设置键盘类型 keyboardType)
[禁止自动纠正 disableAutocorrection](#禁止自动纠正 disableAutocorrection)
[关闭键盘 取消焦点](#关闭键盘 取消焦点)
[背景覆盖 overlay](#背景覆盖 overlay)
[多行编辑 TextEditor](#多行编辑 TextEditor)
单行输入和密码输入 TextField SecureField
示例
单行输入使用TextField和SecureField,区别是SecureField会用*代替输入的字符。
代码:
Swift
struct SwiftUIViewTextField: View {
@State var str: String = ""
var body: some View {
VStack(alignment: .leading, spacing: 20) {
Text("\(str)").frame(minWidth: 120).border(.blue)
TextField("Hello, World!", text: $str)
.border(.blue)
.textFieldStyle(RoundedBorderTextFieldStyle())
.textContentType(.telephoneNumber)
.keyboardType(.numberPad)
.disableAutocorrection(true)
.padding()
SecureField("请输入密码", text: $str).border(.blue)
}.padding().border(.red)
}
}
效果:


双向绑定 $变量
之前我们用过@State变量来自动刷新界面,输入型视图要把输入的内容保存到变量去需要不同的绑定方式,增加符号"$",实现双向绑定。
Swift
TextField("Hello, World!", text: $str)
因为例子中Text和SecureField也绑定到同一个变量,所以三个框会同步变化。
预设格式 textFieldStyle
textFieldStyle的参数指示预设的格式,比如RoundedBorderTextFieldStyle(),圆角带Padding(注意由于设置了border,失去了圆角,这是个冲突)。内置变量.roundedBorder也是一样的。
其余格式PlainTextFieldStyle(或内置变量.plain)和DefaultTextFieldStyle(或内置变量.automatic)差不多,不用设置。
内容类型 textContentType
这是给系统的提示,而不是对内容的约束。系统会根据提示调整键盘的细节,改善用户体验(然而莫名其妙的变化会伤害用户体验)。使用什么键盘是需要自己设置的。
.telephoneNumber 电话号码。
设置键盘类型 keyboardType
一般用到的就是指定数字键盘:
Swift
.keyboardType(.numberPad)
禁止自动纠正 disableAutocorrection
什么时候他们才会意识到全人类都痛恨自动纠正啊。
Swift
.disableAutocorrection(true)
再谈Padding
padding是填充的意思,在四周增加空白,但具体效果不同对象有所不同。
上面的示例给VStack和TextField都设置了Padding和Border,但是明显看出对VStack,填充是在边框之内,而对于TextField,填充却在边框之外,似乎缺乏统一的概念设计。
再谈text
我们注意到text是跟随内容自动变化的,示例代码强制了最小宽度,有内容的时候高度会变大,整个VStack的边框也会变大(红色),这种灵活的效果我不是很习惯。
关闭键盘 取消焦点
我们会发现很多应用输入完数据后键盘不会消失,导致部分界面被遮盖,无法进行下一步。这是因为输入框不会在点击外部空白区域时失去焦点,从而系统认为仍然处于输入状态。
解决方法很简单,输入框有个.focused($isFocus),参数是绑定的布尔变量,用来指示或控制输入框的状态,我们只需要在点击输入框外部空白时将绑定变量设置为false即可。
Swift
@FocusState private var isFocus: Bool //绑定变量
var body: some View
{
VStack
{
TextField(。。。。。。)
.focused($isFocus)//设置绑定变量
}
.padding()
.border(.red)
.background(.green) //这句挺重要
.ignoresSafeArea(.all)
.onTapGesture
{
isFocus = false //取消焦点
}
}
代码不复杂,在外层的onTapGesture设置代码即可,一般应该在最外层的容器上做。
里面有一句设置了最外层容器的背景色,标注了"这句挺重要",为什么呢?因为没有这一句时似乎系统认为顶级容器挺小的,取消焦点这个功能不是很灵,加了这一句就很灵了。注意任何情况下点击顶部安全区都无效,不论是否使用了.ignoresSafeArea(.all)。有一点奇怪,对于VStack,忽略安全区将导致边界正确显示在屏幕最外围,与ZStack不同。
不论是否使用了.ignoresSafeArea(.all),顶级的背景色都是全屏的。
关闭键盘还有些不同的方法,这个方法是官方推荐的方法(但是仍然不是很理想)。
背景覆盖 overlay
可以用overlay修饰TextField,overlay的参数是视图。修改一下之前的TextField:
Swift
TextField("Hello, World!", text: $str)
.font(.system(size: 80))
.border(.blue)
.textFieldStyle(.roundedBorder)
.textContentType(.telephoneNumber)
.keyboardType(.numberPad)
.disableAutocorrection(true)
//.padding()
.overlay(
HStack {
Image(systemName: "magnifyingglass")
.font(.system(size: 80))
Spacer()
}
)
效果:

其实也不是啥好主意。
多行编辑 TextEditor
介绍
多行编辑有两点很不同:没有placeholder参数,默认大小是尽可能大。
还有一点也很不同:必须先隐藏默认背景才能设置背景。(.scrollContentBackground(.hidden))
综合示例
这个例子包含了本篇全部内容:
Swift
import SwiftUI
struct SwiftUIViewTextField: View {
@State var str: String = ""
@FocusState private var isFocus: Bool
var body: some View {
VStack(alignment: .leading, spacing: 20) {
Spacer()
Text("\(str)")
.frame(minWidth: 120)
.border(.blue)
.background(.blue)
.foregroundStyle(.red)
TextField("Hello, World!", text: $str)
.font(.system(size: 80))
.border(.blue)
.textFieldStyle(.roundedBorder)
.textContentType(.telephoneNumber)
.keyboardType(.numberPad)
.disableAutocorrection(true)
//.padding()
.overlay(
HStack {
Image(systemName: "magnifyingglass")
.font(.system(size: 80))
Spacer()
}
)
.focused($isFocus)
SecureField("请输入密码", text: $str)
.border(.blue)
TextEditor(text:$str) //第一个多行文本,设置了背景色和前景色,默认大小
.scrollContentBackground(.hidden)
.background(.gray)
.foregroundStyle(.red)
TextEditor(text:$str) //第二个多行文本,指定了最大高度
.border(.red)
.frame(maxHeight:80)
Spacer()
}
.padding()
.border(.red)
.background(.green)
//.ignoresSafeArea(.all)
.onTapGesture {
isFocus = false
}
}
}
效果:

我们可以看到,Text是能显示多行的,TextField则把多行显示在一行,换行变成了空白。Text很简单地设置了背景色,TextEditor则必须禁用默认背景才能显示自己设置的背景色。TexeEditor的默认大小是尽可能大的。