Сосредоточьтесь на следующем TextField / SecureField в Swiftui - PullRequest
1 голос
/ 17 октября 2019

Я построил экран входа в Swiftui. Я хочу сосредоточиться на пароле SecureField, когда пользователь закончит вводить свою электронную почту. Как я могу это сделать?

struct LoginView: View {
    @State var username: String = ""
    @State var password: String = ""

    var body: some View {
        ScrollView {
            VStack {
                TextField("Email", text: $username)
                    .padding()
                    .frame(width: 300)
                    .background(Color(UIColor.systemGray5))
                    .cornerRadius(5.0)
                    .padding(.bottom, 20)
                    .keyboardType(.emailAddress)

                SecureField("Password", text: $password)
                    .padding()
                    .frame(width: 300)
                    .background(Color(UIColor.systemGray5))
                    .cornerRadius(5.0)
                    .padding(.bottom, 20)

                Button(action: {

                }, label: {
                    Text("Login")
                        .padding()
                        .frame(width: 300)
                        .background((username.isEmpty || password.isEmpty) ? Color.gray : Color(UIColor.cricHQOrangeColor()))
                        .foregroundColor(.white)
                        .cornerRadius(5.0)
                        .padding(.bottom, 20)
                }).disabled(username.isEmpty || password.isEmpty)

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Я улучшил ответ от Джина З. Рагана и Разиба Моллика. Исправляет сбой, это позволяет использовать любое количество текстовых полей, поддерживает пароли и делает его собственным классом.

struct UITextFieldView: UIViewRepresentable {
    let contentType: UITextContentType
    let returnVal: UIReturnKeyType
    let placeholder: String
    let tag: Int
    @Binding var text: String
    @Binding var isfocusAble: [Bool]

    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.textContentType = contentType
        textField.returnKeyType = returnVal
        textField.tag = tag
        textField.delegate = context.coordinator
        textField.placeholder = placeholder
        textField.clearButtonMode = UITextField.ViewMode.whileEditing

        if textField.textContentType == .password || textField.textContentType == .newPassword {
            textField.isSecureTextEntry = true
        }

        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.text = text

        if uiView.window != nil {
            if isfocusAble[tag] {
                if !uiView.isFirstResponder {
                    uiView.becomeFirstResponder()
                }
            } else {
                uiView.resignFirstResponder()
            }
        }
    }

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

    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: UITextFieldView

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

        func textFieldDidChangeSelection(_ textField: UITextField) {
            // Without async this will modify the state during view update.
            DispatchQueue.main.async {
                self.parent.text = textField.text ?? ""
            }
        }

        func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
            setFocus(tag: parent.tag)
            return true
        }

        func setFocus(tag: Int) {
            let reset = tag >= parent.isfocusAble.count || tag < 0

            if reset || !parent.isfocusAble[tag] {
                var newFocus = [Bool](repeatElement(false, count: parent.isfocusAble.count))
                if !reset {
                    newFocus[tag] = true
                }
                // Without async this will modify the state during view update.
                DispatchQueue.main.async {
                    self.parent.isfocusAble = newFocus
                }
            }
        }

        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            setFocus(tag: parent.tag + 1)
            return true
        }
    }
}

struct UITextFieldView_Previews: PreviewProvider {
    static var previews: some View {
        UITextFieldView(contentType: .emailAddress,
                       returnVal: .next,
                       placeholder: "Email",
                       tag: 0,
                       text: .constant(""),
                       isfocusAble: .constant([false]))
    }
}
1 голос
/ 17 октября 2019

При использовании UIKit можно было бы сделать это, настроив цепочку респондента. Это не доступно в SwiftUI, поэтому, пока нет более сложной системы фокусировки и ответчика, вы можете использовать onEditingChanged измененное TextField

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

К счастью, вы можете вернуться к UIKit в SwiftUI с помощью UIViewRepresentable.

Вот некоторый код, который управляет фокусировкой текстовых полейиспользуя систему ответов UIKit:

import SwiftUI

struct KeyboardTypeView: View {
    @State var firstName = ""
    @State var lastName = ""
    @State var focused: [Bool] = [true, false]

    var body: some View {
        Form {
            Section(header: Text("Your Info")) {
                TextFieldTyped(keyboardType: .default, returnVal: .next, tag: 0, text: self.$firstName, isfocusAble: self.$focused)
                TextFieldTyped(keyboardType: .default, returnVal: .done, tag: 1, text: self.$lastName, isfocusAble: self.$focused)
                Text("Full Name :" + self.firstName + " " + self.lastName)
            }
        }
}
}



struct TextFieldTyped: UIViewRepresentable {
    let keyboardType: UIKeyboardType
    let returnVal: UIReturnKeyType
    let tag: Int
    @Binding var text: String
    @Binding var isfocusAble: [Bool]

    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.keyboardType = self.keyboardType
        textField.returnKeyType = self.returnVal
        textField.tag = self.tag
        textField.delegate = context.coordinator
        textField.autocorrectionType = .no

        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
        if isfocusAble[tag] {
            uiView.becomeFirstResponder()
        } else {
            uiView.resignFirstResponder()
        }
    }

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

    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: TextFieldTyped

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

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

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

            if parent.tag == 0 {
                parent.isfocusAble = [false, true]
                parent.text = textField.text ?? ""
            } else if parent.tag == 1 {
                parent.isfocusAble = [false, false]
                parent.text = textField.text ?? ""
         }
        return true
        }

    }
}

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

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...