12 Weeks as an iOS Developer Apprentice
Double digits! Hard to believe it’s already the tenth week. Time flies like Simone Biles when you’re having fun.
I’m feeling more comfortable and familiar with the ins and outs of the architecture of the client project I’ve been working on. It’s a really interesting app for a health start-up called Sonde and it was only one week away from being feature-complete when I came on board.
Initially, there was quite a bit to absorb. It required a lot of time just sifting through files and carefully reading the code that had already been written. Now, solving the tasks I’ve been assigned still requires careful reading, but I have a much better idea of where in the project I can begin to look for what I’m searching for.
It’s been in polish mode since becoming feature-complete which means lots of bug bashing and UI tweaking. I did some work this past week with UIDatePickers, which are a subclass of UIPickerView and quite the classic iOS element.
Drag and drop a date picker right into your storyboard or nib file. Wire it up like any other UI element with an outlet to a view controller and dive right into customization.
The user must go through a registration process in the Sonde app and part of that process is entering their date of birth. Perfect spot for a date picker.
Set up a method to call in viewDidLoad:
To start, we want our date picker to show month, date, and year options so we’ll set the DatePickerMode to .Date
Next, set a minimum and maximum date for the user to choose from so that they aren’t scrolling through the picker view all day to find their selection.
In this example, I’ve set up an extension on NSDate to calculate “n” number of years from the current date.
The user must be at least 18 years old to participate in the research facilitated by this app and although we don’t expect anyone to be close to it, we’ll cap the age at 100 for some wiggle room.
It’s important to keep in mind that we’re setting the minimum and maximum date of our picker view, not the min/max age. So our min date is 100 years in the past, 1916, and our max date is 18 years in the past, 1998.
Lastly, whenever the value of the date picker has changed, i.e. whenever the user has scrolled through the date picker, we want to update the text of our text field.
Create a method that can be called whenever the value of the date picker changes:
Here we use NSDateFormatter and choose a dateStyle and timeStyle from NSDateFormatterStyle to format the date and time. Then we make the text of our textField a string from the date of our date picker with .stringFromDate(date: NSDate)
Add the target (the ViewController) and action (the above method) to the date picker. The ViewController will then perform the method above whenever it receives a notification from UIControlEvents.ValueChanged that the value of the date picker has changed.
And here’s what we have so far:
Now let’s prettify the text field a bit more. Remove the out-of-the-box border and color. Replace them with an opaque, white underline, a clear background, and crisp white text. Also, disable user interaction because we don’t want the keyboard to come up when we already have the date picker.
We can make the font white, disable user interaction, and remove the text field’s border in the Attributes Inspector of the storyboard.
We’ll create the white underline programmatically.
- Create an extension of UITextField
- Drop it in ViewDidLoad
Looking much better:
Next let’s change the date picker’s font color to match the text field. This can be a little tricky as it’s not commonly recommended to customize a UIDatePicker.
Most devs end up subclassing UIPickerView and using it as a date picker. And yes, there are cocoapods that already exist for full customization (like this pretty slick one). But I really only wanted to change the color of the text and was able to find a clean, handy solution in this StackOverflow post.
We must simply set a new value for the key associated with a UIDatePicker’s text color property and the property that handles the highlighting of today’s date.
- For clarity, create an enum to hold the keys
- Set the value for those keys (lines 8 and 9)
Setting the value for the “highlightsToday” key to false is important because by default it is true and all of our text would be white except for today’s date.
Finally, disable the NEXT button until the user has started scrolling through the date picker in order to avoid the chance that the user taps the button before they’ve made a selection.
And while we’re at it, let’s get rid of the age requirement label once scrolling has commenced.
- Start by disabling the NEXT button in ViewWillAppear. That way if the user has on option to come back to this screen it wil always start out as disabled (line 4)
- Then enable the button and hide the label when the date picker value changes (lines 3 and 4)
Also, for an even better user experience, let’s give a visual cue to the user as to whether or not the NEXT button is enabled by changing the alpha of the button.
- Subclass UIButton and override the enabled property to change the value of it’s alpha accordingly
Here, whenever the enabled property has been set, the value of the button’s alpha will be calculated according to whether “enabled” is true or false.
If true, it will be 1.0. If false, it will be 0.3
For this to work, we must change the type of our NEXT button outlet to our new NextButton class in the view controller.
As well as in the Identity Inspector.
And there you have it.
A beautifully customized date picker and text field combo.
Check out the full example project here on GitHub.