Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofocus TextField programmatically in SwiftUI

I'm using a modal to add names to a list. When the modal is shown, I want to focus the TextField automatically, like this:

Preview

I've not found any suitable solutions yet.

Is there anything implemented into SwiftUI already in order to do this?

Thanks for your help.

var modal: some View {         NavigationView{             VStack{                 HStack{                     Spacer()                     TextField("Name", text: $inputText) // autofocus this!                         .textFieldStyle(DefaultTextFieldStyle())                         .padding()                         .font(.system(size: 25))                         // something like .focus() ??                     Spacer()                 }                 Button(action: {                     if self.inputText != ""{                         self.players.append(Player(name: self.inputText))                         self.inputText = ""                         self.isModal = false                     }                 }, label: {                     HStack{                         Text("Add \(inputText)")                         Image(systemName: "plus")                     }                         .font(.system(size: 20))                 })                     .padding()                     .foregroundColor(.white)                     .background(Color.blue)                     .cornerRadius(10)                 Spacer()             }                 .navigationBarTitle("New Player")                 .navigationBarItems(trailing: Button(action: {self.isModal=false}, label: {Text("Cancel").font(.system(size: 20))}))                 .padding()         }     } 
like image 763
Nils Avatar asked Oct 09 '19 19:10

Nils


People also ask

How do I Unfocus a TextField SwiftUI?

If you're supporting only iOS 15 and later, you can activate and dismiss the keyboard for a text field by focusing and unfocusing it. In its simplest form, this is done using the @FocusState property wrapper and the focusable() modifier – the first stores a Boolean that tracks whether the second is currently focused.

How do I create a secure TextField in SwiftUI?

You just make a View with all the code you want for the SecureTextField and the TextField then all you have to do is call the HybridTextField where ever you need it. Save this answer.


1 Answers

Since Responder Chain is not presented to be consumed via SwiftUI, so we have to consume it using UIViewRepresentable. I have made a workaround that can work similarly to the way we use to do using UIKit.

 struct CustomTextField: UIViewRepresentable {     class Coordinator: NSObject, UITextFieldDelegate {        @Binding var text: String       @Binding var nextResponder : Bool?       @Binding var isResponder : Bool?        init(text: Binding<String>,nextResponder : Binding<Bool?> , isResponder : Binding<Bool?>) {         _text = text         _isResponder = isResponder         _nextResponder = nextResponder       }        func textFieldDidChangeSelection(_ textField: UITextField) {         text = textField.text ?? ""       }            func textFieldDidBeginEditing(_ textField: UITextField) {          DispatchQueue.main.async {              self.isResponder = true          }       }            func textFieldDidEndEditing(_ textField: UITextField) {          DispatchQueue.main.async {              self.isResponder = false              if self.nextResponder != nil {                  self.nextResponder = true              }          }       }   }    @Binding var text: String   @Binding var nextResponder : Bool?   @Binding var isResponder : Bool?    var isSecured : Bool = false   var keyboard : UIKeyboardType    func makeUIView(context: UIViewRepresentableContext<CustomTextField>) -> UITextField {       let textField = UITextField(frame: .zero)       textField.isSecureTextEntry = isSecured       textField.autocapitalizationType = .none       textField.autocorrectionType = .no       textField.keyboardType = keyboard       textField.delegate = context.coordinator       return textField   }    func makeCoordinator() -> CustomTextField.Coordinator {       return Coordinator(text: $text, nextResponder: $nextResponder, isResponder: $isResponder)   }    func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<CustomTextField>) {        uiView.text = text        if isResponder ?? false {            uiView.becomeFirstResponder()        }   }  } 

You can use this component like this...

struct ContentView : View {  @State private var username =  "" @State private var password =  ""  // set true , if you want to focus it initially, and set false if you want to focus it by tapping on it. @State private var isUsernameFirstResponder : Bool? = true @State private var isPasswordFirstResponder : Bool? =  false     var body : some View {     VStack(alignment: .center) {                  CustomTextField(text: $username,                         nextResponder: $isPasswordFirstResponder,                         isResponder: $isUsernameFirstResponder,                         isSecured: false,                         keyboard: .default)                  // assigning the next responder to nil , as this will be last textfield on the view.         CustomTextField(text: $password,                         nextResponder: .constant(nil),                         isResponder: $isPasswordFirstResponder,                         isSecured: true,                         keyboard: .default)     }     .padding(.horizontal, 50)   } } 

Here isResponder is to assigning responder to the current textfield, and nextResponder is to make the first response , as the current textfield resigns it.

like image 193
Anshuman Singh Avatar answered Oct 16 '22 23:10

Anshuman Singh