是否可以将 .submitLable() 添加到键盘类型为 .numberPad 的 TextField。我能找到的所有信息都是不可能的,但该信息已有 2 年历史了。所以我希望它可能已经改变了。
我有以下代码,但是当我实际运行应用程序时,提交标签没有出现在键盘上。
TextField("placeholder", text: $placeholder)
.submitLabel(.next)
.keyboardType(.numberPad)
有没有办法在 SwiftUI 中使用 numberPad 键盘类型向 TextField 添加提交标签或类似功能的东西,或者目前 SwiftUI 不可能吗?
问题是
.submitLabel()
修改了键盘中“返回”键的显示/行为,但是对于.numberPad
没有这样的键可以修改。 (您可以通过使用默认键盘类型对 .submitLabel()
的不同值进行试验来看到此行为)
可以使用系统定义和预本地化的
inputAccessoryView
按钮将UITextField
添加到.done
。 (或.next
,或其他几个)虽然有点麻烦。
例如,使用符合
Value
的泛型BinaryInteger
:
struct NumberTextField<Value: BinaryInteger>: UIViewRepresentable {
@Binding var value: Value
func makeUIView(context: Context) -> UITextField {
let textField = UITextField()
textField.keyboardType = .numberPad
textField.delegate = context.coordinator
textField.inputAccessoryView = createToolbar()
return textField
}
func updateUIView(_ uiView: UITextField, context: Context) {
uiView.text = "\(value)"
}
func makeCoordinator() -> Coordinator {
Coordinator(value: $value)
}
private func createToolbar() -> UIToolbar {
// if you want behavior other than "dismiss", put it in action:
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(UIApplication.dismissKeyboard))
let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let toolbar = UIToolbar()
toolbar.sizeToFit()
toolbar.items = [spacer, doneButton]
// you may want to check the locale for right-to-left orientation,
// if it doesn't automatically re-orient the sequence of items.
return toolbar
}
// I don't recall where I got this code, its purpose is mostly to
// filter out non-numeric values from the input, it may be suboptimal
class Coordinator: NSObject, UITextFieldDelegate {
var value: Binding<Value>
init(value: Binding<Value>) {
self.value = value
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let allowedCharacters = CharacterSet.decimalDigits
let characterSet = CharacterSet(charactersIn: string)
return allowedCharacters.isSuperset(of: characterSet)
}
func textFieldDidEndEditing(_ textField: UITextField) {
// if you use a different protocol than BinaryInteger
// you will most likely have to change this behavior
guard let text = textField.text else { return }
guard let integer = Int(text) else { return }
value.wrappedValue = Value(integer)
}
}
}
在这里,
UIApplication.dismissKeyboard
是像这样的 UIApplication
的扩展,它基本上告诉当前有焦点(显示键盘)的任何东西放弃它:
extension UIApplication {
@objc
func dismissKeyboard() {
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
我已经将它与 Swift 5.5 和 iOS 16.x 的目标一起使用。它应该可以与 Swift / iOS 的一些早期版本一起使用,但我还没有用其他任何东西测试过它。