Нажмите клавишу возврата «без» закрытия программной клавиатуры - SwiftUI - PullRequest
0 голосов
/ 08 мая 2020

Я хотел бы создать TextField, где можно быстро ввести несколько элементов String в то же поле, набрав элемент, а затем нажав return , чтобы добавить его .

У меня уже есть функция добавления, однако я не хочу отключать клавиатуру каждый раз, когда элемент добавляется в список после нажатия клавиши возврата, так как пользователям неудобно нажимать каждое текстовое поле время, чтобы вернуть клавиатуру.

Я ищу чистое решение SwiftUI , если возможно.

Что у меня есть:

import SwiftUI

struct StackOverflowSubmissions: 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 StackOverflowSubmissions_Previews: PreviewProvider {
    static var previews: some View {
        StackOverflowSubmissions()
    }
}


1 Ответ

0 голосов
/ 08 мая 2020

Вот 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?()
        }
    }
}

Используйте CustomTextView в ContentView следующим образом:

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)
        }
    }
}
...