I recently attended CocoaLove, a developer conference in Philadelphia. At that conference there was a talk presented by Austin Seraphin, a man who has been blind since birth. When I first saw that he was going to be speaking about Accessibility I was a bit surprised and I did not quite know what to expect. On the one hand, who is going to care about accessibility more than a blind person? On the other, how is a blind person ever going to use a touch screen device? He talked about all of the devices in his life that were able to be replaced by the iPhone and briefly spoke about how easy it is to implement accessibility features as apps are developed. I loved his talk and it made me very interested in learning more about how to actually implement it. I soon discovered that it is quite simple.

This still leaves a question that needs to be answered, though. If you are working on an app, why should you bother with accessibility? It is going to add to the development time and the testing time but what do you, as an app creator, receive in return? There are a couple of answers; first, in my opinion it is the right thing to do. We have these amazing iOS devices that are so powerful and have the ability to work for people who have various disabilities, so you should allow them to use your app also. Second, there is the business answer. If more people can use your app then more people will use your app. This means more downloads and a better bottom line.

This tutorial is not going to be able to go through every possible way accessibility can and should be used, but instead highlight some of the basics. The goal here is to show that it is simple to get your app accessible for everyone with out too much extra work and encourage everyone to use this everywhere. I'm going to break this down into four main topics. Note that I will not be talking about Dynamic Type since a colleague of mine already covered that topic but I do recommend supporting it since your users will expect it. You can find the blog on Dynamic Type here.

The sample code for this tutorial can be found on GitHub. This is a simple, one page app that just has a few UI elements visible to demonstrate how accessibility settings are handled. If the "profile image" is selected it will take up more of the screen so that it can be more easily seen. There are 6 branches in this GIT project. The "master" branch has all of the accessibility features implemented. The "basic" branch has the app with no accessibility features. The remaining 4 are all appropriately named and implement only the accessibility handling for the feature that the name suggests. This structure will allow you to see more clearly what has been changed to implement each feature.

One final note before we dive in. All of these features are new to iOS 8. If you are supporting earlier versions of iOS you will need code to be sure that these new APIs are not called since they will cause a crash in prior versions of iOS. When using Objective-C this is quite simple as you can check each API call in the following way:

if (UIAccessibilityIsBoldTextEnabled != NULL && UIAccessibilityIsBoldTextEnabled()) {
 // This is safe from crashes in iOS 7 
}

Unfortunately, the check for NULL does not work in Swift so you may have to check the version of iOS manually before making the API call.

Here is a screenshot of the app running with none of the accessibility features enabled. As each topic is covered, a screenshot will be displayed with that feature enabled for easy comparison.

Bold Text

If the user's device has bold text enabled there are certain parts of the system that will automatically respond to that. For example, if you are using a default navigation controller in your app, the title at the top of the screen will become bold. But this may or may not happen by default in other places. If you have a standard label in your view and you choose to use a system font, that label will automatically adjust itself to bolder text when this setting is turned on. However, if you want to use a custom font, there is some work to be done here. Before assigning the font to the label, you will need to check if bold text is enabled.

 if (UIAccessibilityIsBoldTextEnabled()) { 
 // use bold font 
 } else { 
 // use standard font 
 }
 

That is all there is to it. Of course, this will need to be added to every UI element in which you assign font.

Reduced Transparency

Much like with bold text, iOS standard elements, such as the UINavigationController, will respond to this setting and will give you the desired effect for free. A UINavigationController will automatically make the background of the header fully opaque. But again, if you have custom UI elements you will need to do a bit of extra work to make your entire app opaque. You may have a UIView with a background color that is partially transparent to enhance the design of your app. This is great, but you should still respect the user's settings. A great example of this is Notification Center. With Reduced Transparency turned on the background of the Notification Center becomes completely solid instead of blurring the home screen and allowing it to show through.

 if (UIAccessibilityIsReducedTransparencyEnabled()) { 
 // use opaque color 
 } else { 
 // use transparent color 
 } 
 

Darker Colors

Some users also like to have darker colors. Similar to reduced transparency and bold text, this helps the users who might otherwise have difficulty reading the screen, be able to easily see distinct UI elements. When this setting is turned on, your app should make appropriate colors darker. For example, a gray color should be come dark gray or even black and a light red color should become dark red. Again, this is easy to implement.

 if (UIAccessibilityDarkerSystemColorsEnabled()) { 
 // use a darker color 
 } else { 
 // use the standard color 
 } 
 

Reduced Motion

Another check you should be doing to help your users get the experience they want while using your app is if they want reduced motion. Reduced motion does not mean no motion. Your app can still have animation to make it unique, but the animation might be a bit different for these users. Many apps have a UI element that zooms in, that is, it starts off small and becomes larger with animation until it is the desired size. This can look very nice, but this would not be appropriate on a device that has reduced motion turned on. Instead, your app should do an animation like fading the UI element onto the screen without adjusting size. Perhaps the best example of this is the process of launching and closing apps. Without the setting turned on the app will appear to grow from the icon to the full size of the phone. When this option is enabled, though, iOS understands what the user wants and will crossfade the app into view instead. This is how you would detect the reduced motion setting.

 if (UIAccessibilityIsReducedMotionEnabled()) { 
 // fade view into place 
 } else { 
 // grow view into place 
 }
 

As you can see all of these are quite simple to implement and they help re-enforce good coding practice by pulling your code that does things like set font and colors into a shared location. If you use a category to set your fonts and colors you will avoid adding this logic to all of your view controllers for every label. That is good practice, anyway, so that if you decide to change a font size, for example, it only has to be changed in one place instead of everywhere that the font or color is used. The one exception to that is the reduced motion setting. It is much harder to re-use animation code but you should always evaluate if the code that you are using can be shared. If you would like to dig deeper into accessibility, Apple, as usual, has several very good resources. There was a talk on accessibility at the 2014 WWDC event. In addition, Apple has provided us with an Accessibility Programming Guide.

The final topic left to discuss is Voice Over. Voice Over is a great feature that can allow people who are unable to read the screen at all to use the phone. This is another very important feature to support, however, I don't think I can do it justice in this post since it is a bit more complex than the rest of these. Watch for my next blog post, which will dive into Voice Over.