是否可以使用 SwiftUI 将键盘上的“返回”键更改为“完成”?

And*_*per 9 swift swiftui

在 SwiftUI 中为 TextField 打开键盘时,我没有找到任何将“返回”键更改为“完成”的链接或指南。

现在可以不自定义 UITextField 吗?

Moj*_*ini 13

iOS 15

您可以textField使用一个简单的修饰符为每个更改返回键:调用submitLabel返回键类型:

在此处输入图片说明 图片来自 WWDC21

此外,如您所见,您可以使用回调来处理返回键按下操作,就像修饰符textFieldShouldReturn可访问的旧函数一样.onSubmit

?? 似乎 Xcode 13 beta 1 上存在一个错误,该错误会阻止此修饰符在某些情况下工作。

  • 好吧,我刚刚发现它在工作表中不起作用。没有床单,效果很好。 (2认同)

tyi*_*ine 11

更新

这不再是一个好的解决方案。在 iOS 15 中,您现在可以添加.submitLabel(.done)修饰符。有关更多详细信息,请参阅 Mojtaba 的回答。


旧答案

我发现的最好方法是将Introspect包添加到您的项目中。

这样做之后,import Introspect在项目文件的任何地方添加。

然后将他们的视图修改器之一添加到您的中Textfield以实现您想要的。我相信这就是你想要的吗?

.introspectTextField { textfield in
  textfield.returnKeyType = .done
}
Run Code Online (Sandbox Code Playgroud)

内省有什么作用?

它公开了要在 SwiftUI 中使用的 UIKit。因此,Textfield您在上面看到的对象可以访问所有UITextfield功能!这是一个包,所以请注意它将来可能会损坏,但现在这是一个不错的选择。

这很好,因为它使您无需为每个视图制作自己的 UIKit 包装器

  • 这是一个非常棒的 Pod,谢谢您的分享。我真的不喜欢这样的解决方法,我认为这是一个天才的方法,直到这些东西可以在 SwiftUI 中更自然地访问。 (3认同)

And*_*per 5

如果有人正在寻找将 UITextField 包装在 UIViewRepresentable 中,那么我有一些代码要分享:

struct CustomTextField: UIViewRepresentable {

    let tag: Int
    let placeholder: String
    let keyboardType: UIKeyboardType
    let returnVal: UIReturnKeyType

    @Binding var text: String
    @Binding var activeFieldTag: Int?
    var totalFields: Int = 0
    @Binding var isSecureTextEntry: Bool
    var textColor: UIColor = .pureWhite
    var font: UIFont = .nexaBold13
    var placeholderTextColor: UIColor = .pureWhite
    var placeholderFont: UIFont = .nexaLight13
    var onEditingChanged: (Bool) -> Void = { _ in }

    var lastActiveFieldTag: Int? {

        // Return, if no active field
        // (It also means textFieldShouldReturn not called yet OR called for last field)
        guard let activeFieldTag = activeFieldTag else {
            return nil
        }
        // Return previous field
        if activeFieldTag > 0 {
            return activeFieldTag - 1
        }
        // Return, if no previous field
        return nil
    }

    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.keyboardType = self.keyboardType
        textField.returnKeyType = self.returnVal
        textField.tag = self.tag
        textField.textColor = textColor
        textField.font = font
        textField.attributedPlaceholder = NSAttributedString(
            string: self.placeholder,
            attributes: [
                NSAttributedString.Key.foregroundColor: placeholderTextColor,
                NSAttributedString.Key.font: placeholderFont,
            ]
        )
        textField.delegate = context.coordinator
        textField.autocorrectionType = .no
        textField.isSecureTextEntry = isSecureTextEntry
        return textField
    }

    func updateUIView(_ textField: UITextField, context: Context) {
        if textField.text != self.text {
            textField.text = self.text
        }
        handleFirstResponder(textField)
        if textField.isSecureTextEntry != isSecureTextEntry {
            textField.isSecureTextEntry = isSecureTextEntry
        }
    }

    func handleFirstResponder(_ textField: UITextField) {

        // return if field is neither active nor last-active
        if tag != lastActiveFieldTag && tag != activeFieldTag {
            return
        }

        // return if field is already active
        if lastActiveFieldTag == activeFieldTag {
            return
        }

        // It creates problem in UI when we press the next button too fast and continuously on keyboard
        //        // Remove focus from last active field
        //        if lastActiveFieldTag == tag {
        //            uiView.removeFocus()
        //            return
        //        }

        // Give focus to active field
        if activeFieldTag == tag {
            textField.focus()
            return
        }
    }

    // Its called when pressing Next button on the keyboard
    // See textFieldShouldReturn
    func updateNextTag() {
        // There is no next field so set activeFieldTag to nil
        if tag + 1 == totalFields {
            activeFieldTag = nil
        } else {
            // Set next field tag as active
            activeFieldTag = tag + 1
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {

        var parent: CustomTextField

        init(_ textField: CustomTextField) {
            self.parent = textField
        }

        func updatefocus(textfield: UITextField) {
            textfield.focus()
        }

        func textFieldShouldReturn(_ textField: UITextField) -> Bool {

            // Give focus to next field
            parent.updateNextTag()
            parent.text = textField.text ?? ""

            // If there is no next active field then dismiss the keyboard
            if parent.activeFieldTag == nil {
                DispatchQueue.main.async {
                    textField.removeFocus()
                }
            } 

            return true
        }

        func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
            DispatchQueue.main.async {
                // To enable user to click on any textField while another is active
                self.parent.activeFieldTag = self.parent.tag
                self.parent.onEditingChanged(true)
            }
            return true
        }

        func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
            self.parent.text = textField.text ?? ""
            DispatchQueue.main.async {
                self.parent.onEditingChanged(false)
            }
            return true
        }

        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            if let text = textField.text, let rangeExp = Range(range, in: text) {
                self.parent.text = text.replacingCharacters(in: rangeExp, with: string)
            }
            return true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

获取go键盘上的按钮。尝试将键盘类型更改为 .webSearch。

// 在 Xcode 12 beta 2 和 iOS 14 上测试

.keyboardType(.webSearch)


mah*_*han 5

iOS 15.0+

macOS 12.0+、Mac Catalyst 15.0+、tvOS 15.0+、watchOS 8.0+

submitLabel(_:)

设置此视图的提交标签。

https://developer.apple.com

Form {
    TextField("Username", $viewModel.username)
        .submitLabel(.done)
}
Run Code Online (Sandbox Code Playgroud)