SwiftUI - How to navigate through TextFields by clicking on return button from keyboard?

Anjali Kevadiya picture Anjali Kevadiya · Sep 26, 2019 · Viewed 7.2k times · Source

I'm working with SwiftUI's TextField View. Mainly i have 2 questions,

1) In Swift, we can set Return Key(Text Input Traits) to Next for TextField from storyboard like this right? For this which modifier to use in SwiftUI?

enter image description here

2) I have two Textfields, how to navigate to the next TextField when i click return/next button from keyboard?

Can anyone help with this Or any other alternative to perform this feature?

My question is about SwiftUI not UIKit one :)

Any help would be much appreciated!!

Answer

Razib Mollick picture Razib Mollick · Sep 29, 2019

To resolve your two problems, you need to work with UIKit from SwiftUI. First, you need to customized TextField using UIViewRepresentable. Here is the sample code for test purposes though the code is not so elegance. I bet, there will be having a more robust solution.

  1. Inside the customized TextFieldType, the Keyboard return type has been set.
  2. By using object binding and delegate methods textFieldShouldReturn, View can focus the keyboard by updating the binding variables.

Here is the sample code:

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
        }

    }
}

Output: enter image description here