Amanreet Bajwa - Big Nerd Ranch Thu, 10 Mar 2022 23:29:54 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.5 Auditing Your App for Accessibility https://bignerdranch.com/blog/auditing-your-app-for-accessibility/ Tue, 09 Mar 2021 16:20:19 +0000 https://www.bignerdranch.com/?p=4737 Getting started with accessibility in your app may be intimidating at first, but there are some handy tools out there to get you started.

The post Auditing Your App for Accessibility appeared first on Big Nerd Ranch.

]]>
Adding accessibility to your app may be an intimidating task, but there are some handy tools out there to get you started quickly. There are a variety of ways to approach your accessibility implementation, but the first step is to perform an audit on your app. By auditing your app, you can identify all of the improvement areas and outline the items needed to make your app fully accessible.

When it comes to auditing your app, there are a variety of tools and methods available to help. Generally, you’ll want to spend time getting familiar with accessibility features and navigating through your app as one of your users. Xcode also provides the Accessibility Inspector, which is a handy way to see what accessibility settings might be missing on User Interface (UI) elements.

Manually Auditing

It’s best to explore the different accessibility options on your iOS device before anything else. Getting familiar with how users navigate apps using assistive technologies is essential to understanding where you should improve your app.

VoiceOver

iOS VoiceOver settingsWhen thinking about accessibility, the first thing that comes to mind is VoiceOver. iOS does a decent job at making labels, buttons, and sometimes images accessible by default, but there is still room for improvement. To tell how accessible your app truly is, enable VoiceOver on your device and run through it as a user. It’s important to both note which elements are focusable (they’ll appear with a box around them when focused and be read aloud) and the overall flow of the focus. To get a full example of using the app as a user, it’s helpful to enable the screen curtain feature which will black out your screen while allowing you to use VoiceOver gestures. Once you have VoiceOver on, the easiest way to toggle screen-curtain is by using the three-finger triple-tap gesture.

Try experimenting with different VoiceOver rotor options to see how elements are focused. If you’re unfamiliar with the rotor, “Getting Familiar with iOS VoiceOver’s Rotor” will get you started.

Display & Text Size

VoiceOver isn’t the only accessibility feature you should explore. “Display & Text Size” is another prominent feature and might be even more widely used than VoiceOver. Some users may be able to see but have a difficult time with small fonts on their devices. In the iOS Accessibility settings, there is an option to increase text size significantly. However, UILabels do not handle this out of the box. To test different font sizes:

  1. Navigate to Settings
  2. Select “Display & Text Size”
  3. Select “Larger Text”

Here you can change the text size with the slider at the bottom of the screen. To use even larger sizes, enable the “Larger Accessibility Sizes” toggle. Now the slider should show an even larger range of sizes.

Returning to your app, take note of which labels, if any, respond to this setting. It’s important to take note if text gets cut off, truncated, or appears incorrectly. Buttons should also scale and increase their text size per the settings. It may be an edge case, but be sure to check the largest size together with the “Bold Text” option (also on the “Display & Text Size” screen) to account for the largest option. Making your app look good and function at the largest size is a great way to ensure all sizes in between will likely work.

Example of dynamic textTip: Try using “Smart Invert” to find items that aren’t inverting but should and vice-versa. The more you track down and fix, the more useful your app will be for accessibility users!

Voice Control

Voice Control is a handy feature that can also aid you in assessing accessibility. It assumes that users have sight and voice and can use their voice to navigate their device using commands like “Swipe left,” “Tap,” etc. There’s also an “Overlay” option where you can enable “Item Names” which provides a nice at-a-glance view of what accessibility sees.

Voice control screenUsing Accessibility Inspector

Manually testing your app to see what is accessible is essential, but there are also tools available that can speed up your assessment by identifying the low-hanging fruit. The Accessibility Inspector can help you step through your app and scan all of the accessibility settings on UI elements for issues to fix. You can find the Accessibility Inspector in Developer Tools:

  1. Navigation to accessibility inspectorOpen the “Xcode” menu in the menu bar
  2. Select “Open Developer Tool”
  3. Select “Accessibility Inspector”

In order to use the Accessibility Inspector to check your app, you’ll have to connect your device to your MacBook or launch your app in a simulator. Once it’s connected, it will show as an option in the device dropdown.

Accessibility inspector device listOnce you’ve chosen the device or simulator, the Accessibility Inspector will show all of the basic settings, actions, element details, and UI element hierarchy. For the purposes of accessibility, we’re going to focus on the “Basic” section. In there, you can see the values set for the accessibilityLabelaccessibilityValueaccessibilityTraits, and the accessibilityIdentifier. By pressing the “Audio” button, you can also hear the label read aloud. Keep in mind that this isn’t always exactly what VoiceOver speaks on a device! For one thing, it does not voice or show the accessibilityHint.

Inspected element cowboy hat detail screenThere are multiple options available for navigating through the focusable elements in your app:

  • inspection pointer Enable the Inspection Pointer which allows you to hover over simulator elements.
  • previous buttonnext button Use the Next/Previous element buttons to manually move through elements in focus order.
  • play button Press the Play button to automatically move through elements as VoiceOver finishes voicing each one.
  • audio button You also have the option to navigate through the elements without any audio by toggling the audio button off.

By going through your app with the Accessibility Inspector, you can verify accessibility settings and perform a more in-depth audit of what is missing.

Inspector Audit

Last but not least, the Accessibility Inspector also has an audit feature! This goes through all of the UI elements on the screen and lets you know which ones may be inaccessible with VoiceOver. It also lets you know which elements don’t support Dynamic Text.

accessibility inspector audit screenSimply switching to the audit screen and pressing “Run Audit” gives you a list of issues to fix. Above, you can see that the screen audited is missing accessibility settings on multiple UI elements, and its labels don’t allow dynamic sizing. The eye button next to each item will show you which UI element the warning is referring to. There is also a button with a question mark in a circle next to that which provides suggestions on how to fix the issue.

audit issue exampleFixing all of these warnings is a great start to making your app more accessible! As you fix issues, you can re-run the audit periodically to check what is left to fix. These tools are a great starting point, but it’s critical to also manually test your app as a user to verify things work as expected when using accessibility options.

Inspector Settings

You might have noticed that there’s a settings button available in the Accessibility Inspector as well. These settings allow you to make real-time adjustments to your app to test accessibility. For example, if you enable Dynamic Text on a label, using the font size slider will change the size of text on the simulator immediately.

increase text size exampleConclusion

Making your app accessible isn’t as daunting as it seems. With all of the tools available and some time to audit your app, you can identify significant usability improvements. Implementing these improvements is a huge win for your users and makes your app more user-friendly for everyone!

Ready to start implementing VoiceOver? “Implementing VoiceOver with a Custom Rotor” provides an example of how to integrate your app with VoiceOver’s rotor.

The post Auditing Your App for Accessibility appeared first on Big Nerd Ranch.

]]>
Implementing VoiceOver with a Custom Rotor https://bignerdranch.com/blog/implementing-voiceover-with-a-custom-rotor/ Tue, 23 Feb 2021 16:45:01 +0000 https://www.bignerdranch.com/?p=4715 Looking to implement VoiceOver accessibility in your application? This post goes over the basics of implementing VoiceOver accessibility and handling custom UI controls with the VoiceOver rotor.

The post Implementing VoiceOver with a Custom Rotor appeared first on Big Nerd Ranch.

]]>
In Part One of our series, we got familiar with the iOS VoiceOver rotor. Next up, we’re going to take a look at how to implement a custom rotor to our VoiceOver.

Getting Started

If you’re looking to add accessibility to an existing application the best way to get started is to perform an audit on the current app. There are many tools available to help with this process but for the purposes of this blog post, we’re going to lean towards a basic manual approach.

You can get a sense of how accessible your app is by enabling VoiceOver on your device and running through your application as a user. While you could wear a blindfold or close your eyes, you’ll probably want to use the screen curtain feature instead. When on, the screen is blacked out. Once you have VoiceOver on, the easiest way to toggle screen-curtain is by using the three-finger triple-tap gesture.

Take note of how the app reacts to different rotor navigation options, what it says when focusing on images, links, buttons, etc. Pay special attention to how and whether UI changes are announced: when a notification pops up or a long-running task completes is this communicated via VoiceOver?

With VoiceOver, you should be able to access all functional elements on the screen, and the focus order should be sequential. Keep an eye on that focus order: some UI elements might become focused out of order when using accessibility out of the box, and you might even inadvertently create a “focus trap,” where next/previous migration gets stuck in a small portion of the UI. These issues are generally easy to fix, and they’re a huge win for users!

Using Apple applications as a test is a great way to get familiar with some standards and how VoiceOver should flow before testing your own application.

Basics

To get started with VoiceOver accessibility implementation the best place to begin is by taking a look at the UIAccessibility documentation. Here you’ll find all of the settings available for your UI components. There are a lot of options there but some of the most commonly used ones are outlined below:

  • accessibilityLabel – Text is spoken to the user when the element is focused.
  • accessibilityHint – A description of what the element does. Hints can be enabled/disabled by the user in settings.
  • isAccessibilityElement – Specifies whether or not this UI element is focusable.
  • accessibilityTraits – Used to describe the UI elements usage, behavior, or state, e.g., isSelected, image, header, etc.
  • accessibilityValue – The value of an element, e.g., progress on a slider or state of a toggle.

Implementation

a cowboy hat with description, rating, and buttonLet’s work through an example starting with a simple rating app. The screenshot above shows a single-page application with a title, image, description, rating, and submit button. The idea here is that the user is able to rate the item shown in the picture. Out of the box, VoiceOver focuses on the labels and buttons which are read out loud and provide some context to the user, but not everything is focusable. As you can see, both the image and the rating control are skipped over completely.

Headings

The accessibility API provides traits that can be used on different UI elements. These let the user know additional details such as usage, behavior, or state. A UI element can have multiple traits associated with it. For example, let’s say you have a UISegmentedControl with multiple options. Since it is a button, it should have the button trait. The selected item should also have the selected trait. As a result, when the user focuses on the selected item, VoiceOver will announce it as both a “button” and “selected.”

Some of these accessibility traits are also used by the rotor to select different elements on the screen. If you’re unfamiliar with the rotor and how to use it, Getting Familiar with iOS VoiceOver’s Rotor provides a quick overview. With this example app, if you use the rotor to select “Headings” and then one-finger flick up and down, VoiceOver responds with, “Heading not found.” Even though the “Authentic Cowboy Hat” title is intended to be the heading for this screen, it’s not recognized as one, because the header trait is not set. To fix this, you can add a header accessibility trait on that label:

titleLabel.accessibilityTraits = [.header]

This marks the label as a header, which in turn allows the rotor to navigate to it when using the headings navigation setting. This setting also causes VoiceOver to announce “heading” after the content of the label.

Images

In this application we want the user to know what it is they are rating. Since the image is not purely decorative, VoiceOver should be able to focus on it and provide a description. If you simply enable VoiceOver on the image, iOS will do its best to describe the image to the user. You can make the image accessible by adding:

productImageView.isAccessibilityElement = true

Now if we run the application again and ask it to read the page from the top, the image proves focusable! Hint: try a two-finger swipe up while VoiceOver is active, which activates “Read from Top.”

Notice that when VoiceOver focuses on the image it says “image, cowboy hat.” The spoken “image” is from the accessibilityTrait for the UIImageView, and the “cowboy hat” is the system trying to describe the image contents to the user. In this case, the image is pretty clear, so it does a good job figuring out what it is. To meaningfully leave a rating, though, the user needs more details about the style of cowboy hat. The spoken text can be changed by adding an accessibilityLabel to the image:

productImageView.accessibilityLabel = "Dark brown leather hat with embellishments"

Now the user has a better understanding of what’s in that UIImageView!

Custom Rotor

Last but not least, a VoiceOver user cannot interact with the star rating control on the screen. This is because it’s a UIStackView with a set of five UIImageViews. To make it even less accessible, the app is using a UITapGestureRecognizer to handle the user interaction with the stack. By default, UITapGestureRecognizers are not accessible and do not function when VoiceOver is turned on. While there are some instances where gesture recognizers can be used with VoiceOver, this particular implementation would benefit from a custom rotor.

UIStackViews aren’t focusable by default, so let’s begin by making it accessible:

ratingStackView.isAccessibilityElement = true

Now the element is selectable, but VoiceOver doesn’t say anything. It needs an accessibilityLabel that describes the current state. Assuming the currentRating variable contains the current star value, we can include that in the label:

// The rating goes from 0 to 4 but the user should hear 1 to 5
ratingStackView.accessibilityLabel = "Rating: (currentRating + 1) out of 5"

At this point, the user can’t really interact with the rating control besides focusing on it and hearing the current state. This is where we can add a custom rotor that allows the user to quickly flick up and down to change their rating of the item.

// The name of the rotor is the title in the rotor item selection and what the user hears
let ratingRotor = UIAccessibilityCustomRotor(name: "Rating Value") { [weak self] predicate -> UIAccessibilityCustomRotorItemResult? in
    guard let self = self else { return nil }

    // When the user flicks up we want to increase the rating and down is used to decrease while keeping it within bounds
    let isFlickUp = predicate.searchDirection == UIAccessibilityCustomRotor.Direction.previous
    let delta = isFlickUp ? +1 : -1
    rating = min(max(0, rating + delta), 4)

    // Handles the UI updates to fill in the stars
    self.setRating(value: rating)

    // Notifies the system that the layout for the rating stack view changed
    UIAccessibility.post(notification: .layoutChanged, argument: self.ratingStackView)

    return UIAccessibilityCustomRotorItemResult(targetElement: self.ratingStackView , targetRange: nil)
}

The code above creates a custom rotor that updates the rating up or down by 1 star with each flick up or down gesture respectively. The final step is to add this rotor to the element that we want it to work on:

ratingStackView.accessibilityCustomRotors = [ratingRotor]

At this point the ratingStackView has a custom rotor called “Rating Value”. When the user focuses on the ratingStackView, VoiceOver automatically says, “Use the rotor to access Rating Value.” This hint lets the user know that there is a rating value option available in the rotor.

rating rotor over image and description of cowboy hatThe app now has a custom rotor! Custom rotors provide endless possibilities when making your app more accessible to VoiceOver users. All of your cool custom controls can easily be made accessible to everyone.

Conclusion

When stepping through the application with VoiceOver, the user can now interact with all of the items and perform the same functions as non-VoiceOver users!

This covers some of the basic settings and uses for VoiceOver functionality. VoiceOver is not just limited to the examples above but they provide a great starting point. Rather than adding accessibility to your app as an afterthought, adding it from the beginning of the app development process and designing with those users in mind makes a big impact on the usability of your implementation.

Suggested challenge: rotors are great for some applications, but this star control would also make sense treated as a slider. Update the code to use the adjustable trait and accessibility value instead of a custom rotor. Which do you find more usable?

Want to play around with the code? You can find the code from this post here.

 

The post Implementing VoiceOver with a Custom Rotor appeared first on Big Nerd Ranch.

]]>
Getting Familiar with iOS VoiceOver’s Rotor https://bignerdranch.com/blog/getting-familiar-with-ios-voiceovers-rotor/ Tue, 09 Feb 2021 15:00:48 +0000 https://www.bignerdranch.com/?p=4703 The VoiceOver Rotor is a key component for iOS accessibility that is often overlooked. It allows users to change VoiceOver settings, select specific content types to focus on, adjust volume, and more. Getting familiar with the rotor and different VoiceOver navigation options is essential to understanding how accessibility implementations affect your application.

The post Getting Familiar with iOS VoiceOver’s Rotor appeared first on Big Nerd Ranch.

]]>
The VoiceOver rotor is a key component for iOS accessibility that is often overlooked. It allows users to change VoiceOver settings, select specific content types to focus on, adjust volume, and more. Getting familiar with the rotor and different VoiceOver navigation options is essential to understanding how accessibility implementations affect your application.

Starting VoiceOver

Starting VoiceOver is easy.

  1. Navigate to Settings
  2. Select “Accessibility”
  3. Select “VoiceOver”
  4. Enable VoiceOver

Tip: The “VoiceOver Practice” page is a great way to try out gestures and see what they do!

Rotor Use Basics

The rotor is accessed by using a two-finger rotation gesture. To bring it up, ensure VoiceOver is enabled, then place two fingers slightly spread apart on the screen. Keep one finger as a pivot point and move the other finger around as if to draw a circle. You should see the dial appear and move between options as you rotate. Enabling an option is as simple as just stopping the gesture with that option selected. Once you have selected an option you can use an up or down one-finger flick gesture to adjust the option. For example, if you select “Speaking Rate” on the rotor then flick up, the rate of speech will increase. VoiceOver will speak and let you know the new rate with every flick up or down.

There are default options that come pre-set with the rotor including characters, words, lines, and speaking rate, but the rotor is not limited to just these options. If you head back to the same VoiceOver menu in Settings there is a rotor menu that allows you to select and reorder the rotor options you wish to use. There are a whole variety of additional navigation options and settings.

screenshot of iOS rotor menuRotor Navigation Example

Let’s go through an example of one of the navigation options:

  1. Enable VoiceOver (Pro tip: ask Siri to “Turn on VoiceOver”)
  2. Launch the Apple News App (ask Siri to “Open Apple News”)
  3. Navigate to a news article
  4. Using the two-finger rotation gesture, pull up the rotor and select “Words”

At this point, you’re set to navigate through the page contents word by word. When you flick down, the system will highlight each word and read it out loud.

animation showing navigation by wordsThere are a variety of different VoiceOver navigation options available in the rotor. You can navigate by characters, words, lines, containers, headings, links, images, and more.

Up Next

Now that you have an understanding of all of the different rotor settings it’s time to get familiar with VoiceOver implementation and make a custom rotor to take your app’s accessibility to the next level!

Further Reading

Apple’s “About the VoiceOver rotor on iPhone, iPad, and iPod touch” introduces the rotor and its capabilities.

The post Getting Familiar with iOS VoiceOver’s Rotor appeared first on Big Nerd Ranch.

]]>