按返回键“不”关闭软件键盘 - SwiftUI

Posted

技术标签:

【中文标题】按返回键“不”关闭软件键盘 - SwiftUI【英文标题】:Press return key "without" dismissing software keyboard - SwiftUI 【发布时间】:2020-05-07 23:33:45 【问题描述】:

我想创建一个 TextField,可以在 same 字段中快速输入多个字符串项目,方法是输入项目,然后点击 return 到添加它。

我已经有了添加功能,但是我不想在每次将项目添加到列表时在点击返回时关闭键盘,因为这对于用户每次点击文本字段以进行操作来说很麻烦把键盘拿回来。

如果可能的话,我正在寻找一个纯 SwiftUI 解决方案

我有什么:

import SwiftUI

struct ***Submissions: View 

   @State var item: String = ""
   var body: some View 

      TextField("Enter item...", text: $item, onCommit: 

         // Add item to CoreData database

      )
         .textFieldStyle(RoundedBorderTextFieldStyle())
         .padding(5)
         .background(Color(.gray))
         .cornerRadius(10)
         .padding()
    


struct ***Submissions_Previews: PreviewProvider 
    static var previews: some View 
        ***Submissions()
    



【问题讨论】:

您是否尝试过实现文本字段委托方法? 我不太熟悉,因为我在不熟悉委托模式等的情况下直接进入了 SwiftUI,所以有时像这样让我很痛苦!我已经用 UIViewRepresentable 制作了一个自定义文本字段视图,但是让事情诚实地工作是一件很痛苦的事情。如果可能的话,只是希望有一个简单的面向未来的 SwiftUI 解决方案。 没有纯粹的SwiftUI 解决方案,但如果您愿意,我可以使用UITextViewUIViewRepresentable 提供更好的解决方案,这对SwiftUI 来说是完全好的。谢谢 那太棒了! 您找到解决方案了吗? 【参考方案1】:

这里是CustomTextField,它不会最小化键盘,而是聚焦下一个CustomTextView。这个过程一直持续到当前的CustomTextField 是最后一个CustomTextField

struct CustomTextField: UIViewRepresentable 
    @Binding var text: String // String value of the TextView
    let placeholder: String // Placeholder Text
    let keyboardType: UIKeyboardType // Keypad layout type
    let tag: Int // Tag to recognise each specific TextView
    var commitHandler: (()->Void)? // Called when return key is pressed

    init(_ placeholder: String, text: Binding<String>, keyboardType: UIKeyboardType, tag: Int, onCommit: (()->Void)?) 
        self._text = text
        self.placeholder = placeholder
        self.tag = tag
        self.commitHandler = onCommit
        self.keyboardType = keyboardType
    

    func makeCoordinator() -> Coordinator 
        Coordinator(self)
    

    func makeUIView(context: Context) -> UITextField 
        // Customise the TextField as you wish
        let textField = UITextField(frame: .zero)
        textField.keyboardType = self.keyboardType
        textField.delegate = context.coordinator
        textField.backgroundColor = UIColor(white: 0.0, alpha: 0.025)
        textField.layer.borderWidth = 0.5
        textField.layer.borderColor = UIColor.tertiaryLabel.cgColor
        textField.font = UIFont.systemFont(ofSize: 16.0, weight: .light)
        textField.layer.cornerRadius = 6
        textField.isUserInteractionEnabled = true
        textField.text = text
        textField.textColor = UIColor.lightGray
        textField.tag = tag
        textField.placeholder = placeholder

        // For left inner padding
        let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: 15, height: 120))
        textField.leftView = paddingView
        textField.leftViewMode = UITextField.ViewMode.always

        return textField
    

    func updateUIView(_ uiView: UITextField, context: Context) 
        uiView.text = self.text
        uiView.setContentHuggingPriority(.init(rawValue: 70), for: .vertical)
        uiView.setContentHuggingPriority(.defaultLow, for: .horizontal)
    

    class Coordinator : NSObject, UITextFieldDelegate 

        var parent: CustomTextField

        init(_ uiTextView: CustomTextField) 
            self.parent = uiTextView
        

        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 

            if let value = textField.text as NSString? 
                let proposedValue = value.replacingCharacters(in: range, with: string)
                parent.text = proposedValue as String
            
            return true
        

        func textFieldShouldReturn(_ textField: UITextField) -> Bool 
            if let nextTextField = textField.superview?.superview?.viewWithTag(textField.tag + 1) as? UITextField 
                nextTextField.becomeFirstResponder()
             else 
                textField.resignFirstResponder()
            
            return false
        

        func textFieldDidEndEditing(_ textField: UITextField) 
            parent.commitHandler?()
        
    

像这样在ContentView 中使用CustomTextView

struct ContentView: View 
    @State var firstName: String = ""
    @State var lastName: String = ""
    @State var email: String = ""

    var body: some View 
        VStack 
            Text("First Name Value: \(firstName)")
            CustomTextField("First Name", text: self.$firstName, keyboardType: .default, tag: 1, onCommit: nil).padding().frame(height: 70)


            Text("Last Name Value: \(lastName)")
            CustomTextField("Last Name", text: self.$lastName, keyboardType: .default, tag: 2, onCommit: 
                    print("Last Name is: \(self.lastName)")
                ).padding().frame(minWidth: 0, maxWidth: .infinity, minHeight: 70, maxHeight: 70)


            Text("Email Value: \(email)")
            CustomTextField("Email", text: self.$email, keyboardType: .emailAddress, tag: 3, onCommit: 
                    print("Email is: \(self.email)")
                ).padding().frame(minWidth: 0, maxWidth: .infinity, minHeight: 70, maxHeight: 70)
        
    

【讨论】:

非常感谢您写下这一切!然而,我所追求的是一个单一的文本字段,我可以在不消失键盘的情况下按回车键,同时实现我自己的 addItem 函数,因此字符串被添加到 CoreData 数据库中。这对于登录表单等看起来很棒,但它不是正是我所追求的。

以上是关于按返回键“不”关闭软件键盘 - SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

在 SwiftUI 中捕获文本字段值而不按返回键 [重复]

按下返回键时隐藏软键盘

csharp 单击文本框的返回键时关闭键盘

QML怎么处理android的back键

按下键盘中的返回键时,UITextView 不记得字体样式

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