Xamarin iOS Validation Text Field Tutorial

I recently began dabbling in mobile development; specifically, with Xamarin iOS. It’s been a great experience and I’m making major progress on a side project that I hope will be in decent enough shape to release to the public in the coming months.

If you’re like me, you’re not an expert in UI/UX or design — nor do you want to spend endless hours pretending to be— but you do appreciate it when your app doesn’t look like a total mess while prototyping and getting functionality laid out.

For this, it’s important to have readily available tools to allow for rapid prototyping while maintaining a clean appearance. I will be giving a tutorial on how to implement one such tool in this post.

I guess this is where I introduce you to my flat and minimal validation text fields:

If this looks like something you might find useful, then keep reading. I’m going to jump straight into it!

I would just like to point out that for this tutorial I am assuming some previous knowledge of Visual Studio and Xamarin iOS. However, if you are completely new and I glance over anything too quickly, I’d be happy to answer questions!

You can reference the complete source code here.

Initial Setup

Let’s start by creating a new single view application.

Once the project loads, open up your storyboard and add a new UITextField and do the following:

  • Give it an identity name (I used NameTextField)
  • Resize it to 275px by 30px
  • Remove the border style
  • Remove the initial text
  • Add placeholder text
  • Optional: Add constraints

You should end up with something similar to this:

You obviously don’t need to use any custom fonts but for this tutorial I used EB Garamond and Oswald. Once you’re happy with your initial view controller, save the storyboard and exit.


Coloring UIView Borders

Now for some actual code. The first thing we will do is add functionality for coloring the borders of a UIView. We will accomplish this via an extension method.

Add a new class file to your project called UIViewExtensions.cs. The initial code looks as follows:

public static class UIViewExtensions

In order to extend UIView we must add our methods to a static class.

public static void ColorBorders

The extension method for coloring the borders of a UIView.

Parameters:

  • this UIView view: TheUIView that this extension method operates on
  • CGColor color: The border color
  • nfloat width: The border width
  • BorderDirection direction: enum specifying which borders to color (see below for more info)

public enum BorderDirection

An enum used to declare which borders of the UIView should be colored. Can be of value Top, Bottom, Left, Right or All.


Next, add the following static readonly variables to the UIViewExtensions class.

Here we add a prefix which will be used for naming border sub-layers added to our UIView for easy retrieval in the future and an array of all border directions (excluding BorderDirection.All )


Now we can add some logic to ColorBorders()

We’ll start by looping through ALL_BORDERS and check each possible border against the direction parameter passed to our method.

If the border should be colored, we use the COLOR_BORDERS_EXT prefix from earlier to create a name for the border layer. The final result will be something like color-borders-ext.Top.

Next, we attempt to find a previously added sub-layer with the same name. If one is found, we can reuse it. If no such sub-layer exists, we instantiate a new CALayer and add it to the UIView.


We must determine the frame of the layer we are coloring. To do this we will add a local function to ColorBorders()

Use of a local function is not necessary by any means but I think it makes sense for this use case.

I would like to point out that these CGRect definitions are created with maintaining the UIView’s size in mind. If you wish, you can alter these frames to extend outward past the UIView’s bounds. You just need to ensure that you set: view.Layer.MasksToBounds = false;


To finish our border coloring functionality, all we need to do is assign our sublayer’s Frame, Name, BorderWidth and BorderColor properties.


Now we can test that our new extension method works!

Open your initial view controller’s backing class and override the ViewDidLoad() method. Inside the method, call ColorBorders() on our NameTextField.

Now, run your app and see what happens!


Bordered Text Field

Before we get to the validation text fields, let’s take our border coloring functionality one step further and create a new class called BorderedTextField.

Create a new class file named BorderedTextField.cs and populate it like so:

This gives us a clean way to define and color our text fields which will take some unnecessary bulk out of the validation text field class.

Go back to the view controller backing class and replace:

with

Once you run your app, the text field should look exactly the same as it did earlier.

Great, onto the validation text fields!


Validation Text Fields

Let’s create a new class file called ValidationTextField.cs. Like our extension method, we will also add an enum to this file for tracking the field’s validation state.

The constructor accepts an instance of BorderedTextField as its only parameter. We will add more to the constructor in a minute but for now we hold onto the BorderedTextField and set all state colors to the initial border color of the provided text field.

We also created an enum for tracking the field’s validation state. The field can have a state of Neutral, Valid or Error.


Error Label

Next, we will add a UILabel with the purpose of outputting any validation errors.

To do this we create a private UILabel class variable that is instantiated in the constructor and added to the text field’s superview (parent view).

Okay so there is a good amount added here:

We added a UILabel for displaying validation errors as well as a public property that adds some optional customization of the error font.

The font is initially set to mimic the text field font in the constructor. Since it is likely we don’t want them to be exactly the same size, or even the same font family, we can use this property to update the error label’s font. It will set the font and resize the label as needed.

If you used constraints as I did, the final size of frames will not be correct when overriding the view controller’s ViewDidLoad() method. To remedy this, we added a method call Reframe() that can handle resizing the error label’s frame once all subviews have been laid out. We will call it from the view controller’s backing class later on.

In the constructor we find the text field’s superview. In our case, this is the view controller containing the text field. We instantiate the error label, set the text alignment to Center (feel free to change this as you’d like) and set the ErrorFont property mentioned above to the font of the text field. Once this is all complete, the error label is added to the superview as a subview.


Text Field Editing

Aside from validation state colors, we will add a color specifically for when the text field is being edited. To do so, we will add a new CGColor property and events for when editing begins and ends.


Triggers

Next, we will start implementing how we will handle validation. We will use events that trigger either error or neutral states. Anything else will be considered success. To do so, we will add a new internal class called Trigger, a private list of triggers for both the error and neutral states and a public methods for adding new triggers.

Important Note on Trigger Functions

Because these functions are running asynchronously, we cannot use any UIKit related properties or methods without invoking them on the main thread. I am not going to dive too deep into this now but you can read more on it here.

Essentially, our trigger functions cannot reference other Views, Labels, Buttons, etc.

An example of this would be if you want to compare a password field to a confirmation password field during sign up.

For now, let’s keep our trigger functions simple and I will cover a work around in a second post if anyone is interested.


Validation

Now that we have our triggers implemented we are getting close!

Let’s add our validation logic to ValidationTextField. It will check for a match against neutral triggers first, then error triggers and everything else will be considered a valid state.

Note that the text field’s current text value is pulled before the tasks are ran. This is because of what I mentioned above. If we were to attempt to read the text in an asynchronous thread, we would get an exception.

Okay. Now we want to call this from a new public async method called Validate() .

Next, we will use the trigger returned to update the validation field.

Last but not least, let’s make sure we call Validate() when the field has finished editing!

Alright, let’s go back to our view controller’s backing class to test it all out!


I will be going through each piece of code here, but first, there is one line that I added for the purpose of this tutorial:

It calls the following extension method in our UIViewExtensions class:

This method enables functionality that ends editing of whichever view is currently focused when the view controller is tapped. This isn’t necessary in all apps (nor is it always a good idea because it may interfere with other user touch interactions) but for our testing we have no other views, buttons or text fields to tap and complete editing.


The last thing for us to do is build and run our app and test the validation!

If all went well, it should result in something similar to the following:

I really hope some of you found this useful. If you have any questions or feedback I would love to hear so please reach out. Otherwise, thank you for reading!

Once again, you can reference the complete source code here.