FirstResponder & :onCommit on TextField in SwiftUI

3.4k views Asked by At

In a SwiftUI app, I need to set the focus on a TextField and bring the keyboard automatically, in standard Swift this would be done with:

  field.becomeFirstResponder()

But this does not seem to exist in SwiftUI.

I found a work around here.

But, my field uses :onCommit; which is not in the sample code.

What is the way to set the :onCommit functionality when using UIViewRepresentable ?

3

There are 3 answers

2
swift code On

There is an open-source project for your needs, at https://github.com/mobilinked/MbSwiftUIFirstResponder

TextField("Name", text: $name)
    .firstResponder(id: FirstResponders.name, firstResponder: $firstResponder, resignableUserOperations: .all)

TextEditor(text: $notes)
    .firstResponder(id: FirstResponders.notes, firstResponder: $firstResponder, resignableUserOperations: .all)
0
AlphaWulf On

iOS 15+ has a solution for this.

@FocusState combined with the focused(_:) modifier can be used to control first responder status for textfields.

struct ExampleView: View {
    
    @FocusState private var isFocused: Bool
    
    @State private var textInput = ""
    
    var body: some View {
        TextField("Example", text: $textInput)
            .focused($isFocused)
        
        Button("Confirm") {
            if textInput {
                isFocused = true
            }
        }
    }
}
0
Stanislav Ageev On

For iOS15 There is a solution implemented by apple (as mentioned by @AlphaWulf)

For iOS14 In my opinion, the best approach is to implement your own version of TextField using the UIRepresentable protocol. This might sound like something difficult but it is actually quite simple.

Why it is better to implement your own text field over the solutions using view hierarchy introspection?

One is that a solution based on traversing underlying views is hacky by nature and even a minor iOS version update might break it.

Secondly, in a real-world app, you will want to set additional things on the text field (like return button type and supplementary view) but Apple didn't make a way of doing so and you will be forced to wrap a UITextField in any case.

https://blog.agitek.io/swiftui-2-first-responder-b6a828243268

In this post I have a detailed solution that is similar to what Apple has implemented in SwiftUI 3.