Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
441 views
in Technique[技术] by (71.8m points)

ios - Focus on the next TextField/SecureField in SwiftUI

I've built a login screen in SwiftUI. I want to focus on the password SecureField when the user is finished entering their email. How can I do this?

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)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When using UIKit, one would accomplish this by setting up the responder chain. This isn't available in SwiftUI, so until there is a more sophisticated focus and responder system, you can make use of the onEditingChanged changed of TextField

You will then need to manage the state of each field based on stored State variables. It may end up being more work than you want to do.

Fortunately, you can fall back to UIKit in SwiftUI by using UIViewRepresentable.

Here is some code that manages the focus of text fields using the UIKit responder system:

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
        }

    }
}

You can refer to this question to get more information about this particular approach.

Hope this helps!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...