SwiftUI TextField之事件、焦点、键盘Keyboard
所属分类:ios | 浏览:1528 | 发布于 2023-12-10
这是一篇对SwfitUI的键盘Keybaord的学习笔记,开发的iOS App不可避免的会和TextField等打交道,这个时候需要对键盘进行控制,主要要控制两点:
- 键盘的类型
 - 键盘的显示与隐藏
 
本文主要包含以下内容:
- 键盘类型keyboardType
 - 输入建议textContentType
 - 键盘的显示与隐藏
 
事件
1、onEditingChanged
当 TextField 获得焦点时(进入可编辑状态),onEditingChanged将调用给定的方法并传递true值;当 TextField 失去焦点时,再次调用方法并传递false。
2、onCommit
当用户在输入过程中按下(或点击)return键时触发 onCommit(无法通过代码模拟触发)。如果用户没有点击return键(比如直接切换至其他的 TextField),将不会触发 onCommit。触发 onCommit 的同时,TextField 也将失去焦点。
3、onSubmit
onSubmit 是SwiftUI 3.0 的新增功能。onCommit 和 onEditingChanged 是每个 TextField 对自身状态的描述,onSubmit 则可以从更高的角度对视图中多个 TextField 进行统一管理和调度。
onSubmit 的触发条件同 onCommit 一致,需要用户主动点击return。
当视图中有多个 TextField 时,通过 onSubmit 和 FocusState(下文介绍)的结合,可以给用户带来非常好的使用体验。
焦点
在iOS15中,SwiftUI提供了FocusState属性包装器,用来帮助我们判断该视图内的TextField是否获得焦点。通过focused将FocusState与特定的TextField关联起来。
关于FocusState,请看这篇文章:https://wenge365.com/a/NHJTaFFYSTB0a3Y2cXdKcDVuMTVnZz09.html
键盘
1、键盘类型keyboardType
在swiftui中,可以使用keyboardType()修饰符来设定键盘类型,来方便用户的录入或者录入字符输入范围。
示例代码:
TextField("Price:",value:$price,format: .number.precision(.fractionLength(2)))
    .keyboardType(.decimalPad) //支持小数点的数字键盘

目前SwiftUI支持的键盘类型有11种,分别是:
public enum UIKeyboardType : Int, @unchecked Sendable {
    case `default` = 0 
    case asciiCapable = 1 
    case numbersAndPunctuation = 2 
    case URL = 3
    case numberPad = 4
    case phonePad = 5
    case namePhonePad = 6
    case emailAddress = 7
    @available(iOS 4.1, *)
    case decimalPad = 8
    @available(iOS 5.0, *)
    case twitter = 9
    @available(iOS 7.0, *)
    case webSearch = 10
    @available(iOS 10.0, *)
    case asciiCapableNumberPad = 11
}
2、输入建议textContentType
在某些时候,在录入文字的时候会在键盘上面自动提示我们需要输入的内容,比如电话、邮件、验证码等,这些都是通过textContentType()修饰符来实现的。
示例代码:
SecureField("password", text: $password)
    .textContentType(.password)

可以设定的textContentType种类有很多,其中使用比较多的是:
- password
 - 姓名的选项,如:name、givenName、middleName 等等
 - 地址选项,如 addressCity、fullStreetAddress、postalCode 等等
 - telephoneNumber
 - emailAddress
 - oneTimeCode(验证码)
 
3、键盘的显示与隐藏
键盘显示,当点击输入框时,输入框获取焦点,会自动弹出键盘以供用户输入。
键盘隐藏,相对于来说,键盘隐藏就麻烦的多,目前有两种可行的方式来隐藏键盘:
- 点击键盘上的return键
 - 在键盘工具栏上增加一个完成按钮来隐藏键盘
 - 点击其它空白区域隐藏键盘
 
3.1、点击键盘return键
有时间键盘上没有return键,可以利用下面提到的SubmitLabel来设置return键。
TextField("username", text: $userename).submitLabel(.done)
3.2、在键盘工具栏上增加一个完成按钮来隐藏键盘
VStack {
    // 你的内容
}
.toolbar {
    ToolbarItem(placement: .keyboard) {
        HStack {
            Spacer()
            Button {
                // 方法一:如果使用了FocusState,将focusState设置为nil即可
                // focusState = nil
                // 方法二:使用系统的endEditing()修饰符
                let window = UIApplication.shared.connectedScenes
                    .map({$0 as? UIWindowScene})
                    .compactMap( {$0} )
                    .first?.windows.first ?? UIWindow()
                window.endEditing(true)
            } label: {
                Image(systemName: "keyboard.chevron.compact.down").foregroundStyle(.gray)
            }
        }
    }
}
3.3、点击其它空白区域隐藏键盘
ZStack {
    Color.white
        .onTapGesture {
            let window = UIApplication.shared.connectedScenes
                .map({$0 as? UIWindowScene})
                .compactMap( {$0} )
                .first?.windows.first ?? UIWindow()
            window.endEditing(true)
        }
    TextField("username", text: $username)
}
4、自定义SubmitLabel
默认情况下,TextField(SecureField)在键盘上对应的 submit 行为按钮为return,通过使用 SwiftUI 3.0 中新增了submitLabel修饰器,我们可以将return按钮修改成更符合输入上下文的显示文字。
如图

目前支持的种类有:
- continue
 - done
 - go
 - join
 - next
 - return
 - route
 - search
 - send