UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Fixing Guess the Flag

Paul Hudson    @twostraws   

Way back in project 2 we made Guess the Flag, which showed three flag pictures and asked the users to guess which was which. Well, based on what you now know about VoiceOver, can you spot the fatal flaw in our game?

That’s right: SwiftUI’s default behavior is to read out the image names as their VoiceOver label, which means anyone using VoiceOver can just move over our three flags to have the system announce which one is correct.

To fix this we need to add text descriptions for each of our flags, describing them in enough detail that they can be guessed correctly by someone who has learned them, but of course without actually giving away the name of the country.

If you open your copy of this project, you’ll see it was written to use an array of country names, like this:

@State private var countries = ["Estonia", "France", "Germany", "Ireland", "Italy", "Nigeria", "Poland", "Spain", "UK", "Ukraine", "US"].shuffled()

So, the easiest way to attach labels there – the way that doesn’t require us to change any of our code – is to create a dictionary with country names as keys and accessibility labels as values, like this. Please add this to ContentView:

let labels = [
    "Estonia": "Flag with three horizontal stripes. Top stripe blue, middle stripe black, bottom stripe white.",
    "France": "Flag with three vertical stripes. Left stripe blue, middle stripe white, right stripe red.",
    "Germany": "Flag with three horizontal stripes. Top stripe black, middle stripe red, bottom stripe gold.",
    "Ireland": "Flag with three vertical stripes. Left stripe green, middle stripe white, right stripe orange.",
    "Italy": "Flag with three vertical stripes. Left stripe green, middle stripe white, right stripe red.",
    "Nigeria": "Flag with three vertical stripes. Left stripe green, middle stripe white, right stripe green.",
    "Poland": "Flag with two horizontal stripes. Top stripe white, bottom stripe red.",
    "Spain": "Flag with three horizontal stripes. Top thin stripe red, middle thick stripe gold with a crest on the left, bottom thin stripe red.",
    "UK": "Flag with overlapping red and white crosses, both straight and diagonally, on a blue background.",
    "Ukraine": "Flag with two horizontal stripes. Top stripe blue, bottom stripe yellow.",
    "US": "Flag with many red and white stripes, with white stars on a blue background in the top-left corner."
]

And now all we need to do is add the accessibilityLabel() modifier to the flag images. I realize that sounds simple, but the code has to do three things:

  1. Use countries[number] to get the name of the country for the current flag.
  2. Use that name as the key for labels.
  3. Provide a string to use as a default if somehow the country name doesn’t exist in the dictionary. (This should never happen, but there’s no harm being safe!)

Putting all that together, put this modifier directly below the rest of the modifiers for the flag images:

.accessibilityLabel(labels[countries[number], default: "Unknown flag"])

And now if you run the game again you’ll see it actually is a game, regardless of whether you use VoiceOver or not. This gets right to the core of accessibility: everyone can have fun playing this game now, regardless of their access needs.

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

BUY OUR BOOKS
Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 4.5/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.