Hacktober 2017 Log #3 – Grouping views


Hacktober finished! Hacktober is an event hosted by Github and DigitalOcean to promote contributing to open source. And for this year, I decided on a theme; improving accessibility. And to keep track of what I learned, I’ll be maintaining a log here.

Hacktober finished a couple of weeks ago, and thankfully I managed to complete it properly. For this third and last log of this year, I’ll improve some final bits of the CocoaHeadsNL app.

One of the more overlooked sections of any app is the About screen. But they’re often still important, even if it’s just to tell people what your app or company is all about. However, because they’re usually full of information, adding proper VoiceOver is a big boon.

Grouping views to improve accessibility

The About screen in this app consists of a UITableViewController, that has a tableview header that contains information about CocoaHeadsNL, in two sections. However, when we enable VoiceOver, each of these sections is considered to be a separate element. That’s less than ideal, since you would want to hear this in one continuous flow.

Screenshot of About screen, where all the information is broken up in little pieces instead of one continuous flow.

First, looking at interface builder, we can see that the header view is set up with AutoLayout. While not strictly necessary, let’s change that to a UIStackView.

To actually improve the accessibility, we turn to another technique. We want to keep all the different views, but we want to group them together. To achieve this, we group all the relevant views together in one single container view and then disable accessibility for them.

containerView.isAccessibilityElement = true

for view in containerView.subviews {
	view.isAccessibilityElement = false
}

Then, we add all the accessibility elements for the labels together and group them in the container view.

private func applyAccessibility() {

    let what = NSLocalizedString("What is Cocoaheads?")
    let whatAnswer = NSLocalizedString("A monthly meeting of iOS and Mac developers in the Netherlands and part of the international CocoaHeads.org.")
    let how = NSLocalizedString("How does it work?")
    let howAnswer = NSLocalizedString("Every month we organize a meeting at a different venue including food and drinks sponsored by companies. Depending on the size of the location we put together a nice agenda for developers.")

    whatIsLabel.text = what
    whatIsExplanationLabel.text = whatAnswer
    howDoesItWorkLabel.text = how
    howDoesItWorkExplanationLabel.text = howAnswer

    tableHeaderView.isAccessibilityElement = true
    tableHeaderView.accessibilityLabel = [what, whatAnswer, how, howAnswer].joined(separator: " ")
}

Done!

Adding purpose with accessiblityHint

The tableview itself is filled with a list of contributors to the app, which is updated from Github directly. If you select a contributor, you’re brought to their Github profile page, which is pretty interesting. However, when you listen with VoiceOver, only the name is read out, so a VoiceOver user would not know about this functionality.

Screenshot of the contributors list, where only the name is read out loud.

So, how would you improve this? You can start by adding UIAccessibilityTraitButton, to indicate that it can be double-tapped. And afterwards, setting the accessibilityHint will give the user information about the effects of selecting it.

cell.textLabel?.text = contributor.name ?? NSLocalizedString("Anonymous")
cell.accessibilityTraits = cell.accessibilityTraits | UIAccessibilityTraitButton
cell.accessibilityHint = NSLocalizedString("Double-tap to open the Github profile page of \(contributor.name ?? NSLocalizedString("this contributor")) in Safari.")

So, now we hear:

Bruno Scheele

Double-tap to open the Github profile page of Bruno Scheele in Safari.

Nice! Now the intended purpose of the cells is clear as well!

Wrapping up

Grouping subviews into one accessibilityElement is an easy way to improve the VoiceOver flow for many complex views. And adding an accessibilityHint allows VoiceOver users to know what interacting with UI elements will do.

You can check out the merged pull request! And hopefully I can follow up with pictures of the Hacktober t-shirt soon as well! 😄