UITextField Form with Previous/Next Keyboard Accessory Input View as Extension (iOS/Swift)

UITextField keyboard input accessory view UIToolbar

UPDATED:

Now use a scrollview instead of moving the view around. See the bottom of this post.

Here’s how to easily, quickly create a manager for a form of UITextFields including Previous/Next buttons on a toolbar above the keyboard. It uses an extension on the UIViewController so it’s non-intrusive.

All you have to do is create your UITextField form and set the tag value for each UITextField to be a unique, ascending value: 0,1,2,3…

The code for the project is at the bottom (as you might suspect) so feel free to download and use that.

UITextField form with Keyboard Input Accessory View UIToolbar for Previous/Next Buttons

Here’s the process…

  1. Create your UITextField form in Interface Builder and set each text field’s tag value to an incrementing value. 0 is the first field of the form, 1 is next, etc.
UITextFields with incrementing tag values
UITextFields with incrementing tag values

2. Create the UIViewController extension… I’ll break this step down…

Prep the UITextFields:

This first function preps the text fields. It cycles thru the subview of the UIViewController’s view searching for UITextField instances. When it finds one, it sets the delegate the self and sets the keyboard return to ‘Next’ (it stores the last text field – designated by the largest tag value – to set the return key to ‘Send’ at the bottom).

Notice the tbKeyboard and tfLast variables outside of the extension – this is because extensions can’t have stored properties.

First Field, First Responder

This function cycles through the view’s subviews looking for the text field w/ the tag of 0. When it finds it, it makes it the first responder.

This is so when your form is displayed, the keyboard comes up with the first field already active. This is optional. Feel free to not call it.

Set the Keyboard Input Accessory

Since the the view controller is the delegate of the text field, this function will be called whenever a new text field is going to become the first responder. Notice we always return true at the end to allow the text field to become active.

If the toolbar hasn’t been created yet, create it w/ the 3 buttons: Previous, Next and Submit. Each button has it’s own selector to call which we’ll get to soon. Hold on!

We set the toolbar as the text field’s input accessory view so it displays above the keyboard.

Find a Text Field by Tag

We cycle recursively thru the view’s subviews looking for the elusive, red-bellied text field with matching tag value.

NOTE: Instead of storing the tfLast as a text field, we could have just stored the largest tag and then used this function to find it and set its keyboard return key to ‘Send.’ 😉

Make Previous/Next First Responder

Here’s where it comes together… if ‘next’ is true, we’re going to make the next text field active. If false, the previous. First we find the current first responder in the view (see below) and optionally bind it to fr as a UITextField.

Then we call findTextField (see above) with either the tag plus 1 (for next) or -1 (for previous) and optionally bind that to tf.

Let’s break things up with a pic…

Easy Form Manager for Prev/Next Buttons
Easy Form Manager for Prev/Next Buttons

Then we set tf to first responder and return true. If something didn’t play out, we return false.

Previous/Next Button actions

For the buttons we created in the tool bar, we have matching functions for previous and next.

Each simply calls the makeTFFirstResponder (see above) with either false (previous) or true (next).

Easy.

Next Return Key function

Then the user taps ‘Next’ on the keyboard, this is called. It tries to go to the next text field. If it doesn’t (false is returned), it assumes it’s on the last text field and calls submitForm (see below) to submit the form however you need.

It returns false ultimately because we don’t want to allow the return key to actually be allowed in the text field.

Submitting the Form

The Submit button on the toolbar also has a function that just called submitForm. The submitForm function is just a placeholder to be overridden in your actual instance of UIViewController.

This version of submitForm ends editing so the keyboard goes away. You can call it in your version if you want.

UIView extension to find the current first responder

I mentioned this was coming so don’t say you’re surprised. This is an extension for UIView that finds the current first responder. Since our text fields and other views are subclasses of UIView, we can recursively call this function and check self for first responder.

For each of the subviews, if it’s the first responder, return it. Otherwise, call this same function on it (recursive).

Another way to do this would be to store the current text field (when textFieldShouldBeginEditing is called – you know this will be the current first responder). But I’m trying to create a small footprint. Also, you would then have to clear that out if you ended editing.

Your UIViewController Class

So your viewDidLoad calls the prepTextFields function to set the delegate and keyboard return key (‘Next’ or ‘Send’).

Your viewDidAppear calls firstTFBecomeFirstResponder to activate the first field.

And your version of submitForm calls the super version to ending editing and then whatever else you need to do: validate the fields, store the data, communicate w/ the server. Don’t look at me!

Hopefully you agree it’s very little code and very little in interface builder. Enjoy. Share improvements please. 🙂

So fine – it wasn’t really 2 steps but I think it always looks good to put things in steps so people know it’s been thought through.

Here’s the whole file put together…

Your two lines are prepTextFields() and firstTFBecomeFirstResponder() – really you only need the prepTextFields call so 2 lines of code was an overestimation.

Of course you have to write the code to submit the form but… 😉

Thanks for reading or just skipping here. Both have goodness sprinkled on them…

Here’s the Code

Xcode Project: PrevNextForm

 

UPDATED version with UIScrollView

 

To make this work with a scrollview (instead of moving the view around). We need to add a scrollview, place our form on it and move it accordingly. I’m doing it all programmatically because we already have everything else.

So add these properties (including changing the vToMove to have a didSet):

In the checkForPlacement function, create the scroll view if it doesn’t exist (it will be set to nil each time a new form is created which is when vToMove should be set):

The new animated change block changes the frame of the scrollview (just the first time – see firstTime) and animates to the field:

 

 

Here’s the whole thing with the scrollview changes: