如何使用 numberPad 将 .submitLabel() 添加到 SwiftUI TextField()

问题描述 投票:0回答:1

是否可以将 .submitLable() 添加到键盘类型为 .numberPad 的 TextField。我能找到的所有信息都是不可能的,但该信息已有 2 年历史了。所以我希望它可能已经改变了。

我有以下代码,但是当我实际运行应用程序时,提交标签没有出现在键盘上。

TextField("placeholder", text: $placeholder)
    .submitLabel(.next)
    .keyboardType(.numberPad)

有没有办法在 SwiftUI 中使用 numberPad 键盘类型向 TextField 添加提交标签或类似功能的东西,或者目前 SwiftUI 不可能吗?

swiftui textfield uikeyboardtype
1个回答
0
投票

问题是

.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 的一些早期版本一起使用,但我还没有用其他任何东西测试过它。

© www.soinside.com 2019 - 2024. All rights reserved.