SwiftUI 2 — First Responder

Stanislav Ageev
Agitek Softworks Inc.
3 min readJul 22, 2021

--

SwiftUI is an amazing framework, but it is still very raw and missing some key features. One of those features is the ability to programmatically manipulate the first responder state of a responder object.

Photo by Elena Taranenko on Unsplash

Why is this important? Let's consider a common situation where we have a form and upon tapping the return key we want to move the focus to the next field and… SURPRISE, you can’t do that in SwiftUI, at least not out of the box.

In UIKit we can simply use the textFieldDidEndEditing() of UITextFieldDelegate to call becomeFirstresponder() of the next field, but SwiftUI doesn’t expose us a way to interact with it. In fact, the only available action on the default SwiftUI text field is to end editing upon tapping the return key.

If you search through the web then you will stumble upon different suggestions on doing this and a lot of them include using the Introspect library or other hacky and version dependent ways.

So what can we do to solve this problem? Use our own implementation of TextFeld by wrapping a UITextField with a UIViewRepresentable protocol. Moreover, we want a universal solution that will always work and won’t require copy-pasting code for each form we build.

Let’s Code!

First, we will create a coordinator for our text field.

As you can see we pass in the callbacks that we will be triggering on start, end, and return events. Nothing complex here.

Next, we‘re going to write our text field wrapper.

Here is the real meat of the solution but most of it is trivial and self explanatory.

The main idea of the solution is that you have one state variable per form, screen, view to track the current first responder. By giving each field a unique id we can then set the current first responder by assigning the corresponding value to the state variable.

The only requirement is for the type of id and the first responder to conform to the Hashable protocol. That allows us to not care much about the type and compare it safely in our code, which we do.

While we can use simple ints or strings as our id types, a much preferable way is to use enums to represent field ids. This leads to clean, readable, and type-safe code.

The above code is a simple implementation and it can be improved upon to use chaining to look more idiomatic.

Conclusion

In SwiftUI 3 that Apple announced in June 2021, the first responder problem was solved in a similar fashion and a solution was implemented for the built-in TexFields (Other Responders?).

My solution was implemented before I saw or read about the changes in the new version and I’m happy to see that great minds think alike (ahaha).

While it is true that the updates in the new version make my solution obsolete, but most of us will be working with SDK 14 at least for one more year, and this code is a great pain relief for a lot of developers who want to use SwiftUI right now.

--

--