Tips and tricks to build accessible iOS apps
#365DaysIOSAccessibility
RSS Feed#365DaysIOSAccessibility
RSS FeedA year-long journey exploring iOS accessibility, one day at a time. Each post shares practical insights, tips, and techniques to make your iOS apps more accessible.
Today starts the #WWDC22 . Apple announces what new APIs we'll be able to use to make more inclusive and accessible apps. There's also Labs, Digital Lounges and Sessions, for free. Check out the schedule here: https://developer.apple.com/wwdc25/topics/accessibility-inclusion/ Last year, Apple presented Audio Graphs to make graphs more accessible. This year, they introduced Swift Charts, that lets you build a wide variety of charts in SwiftUI and they have great VoiceOver support. https://developer.apple.com/documentation/Charts @dnlyong has a great thread going through lots of the new accessibility features presented this year. https://x.com/dnlyong/status/1533897274274639873 As noted by @RobRWAPP and @mecid, Apple is tweaking the style of the SwiftUI accessibility modifiers. https://x.com/RobRWAPP/status/1533900962615762945 Sessions this year include topics like gaming (with Unity), localisation and internationalisation. You can check these (as they get published during the week) and previous accessibility sessions here: https://developer.apple.com/videos/accessibility-inclusion/ SwiftUI lets you now add multiple accessibility actions at once and quick actions to be show by the system when active: https://developer.apple.com/documentation/swiftui/view/accessibilityactions(_:)?changes=latest_minor https://developer.apple.com/documentation/swiftui/view/accessibilityquickaction(style:content:)?changes=latest_minor
Do you have a fancy custom loading animation instead of an UIActivityIndicatorView? You may want to check if it has an accessibility label so a VoiceOver user knows that something is happening. Something like "In progress" or "Loading" could work.

You can check if some features, like VoiceOver, are on. Experiences should not diverge too much. It could be used to avoid auto-hiding UI elements. iOS probably checks this to show search fields by default, without having to pull them down. From the documentation: isVoiceOverRunning: https://developer.apple.com/documentation/uikit/uiaccessibility/isvoiceoverrunning

Two more examples on better accessibility labels for abbreviations. "4 days ago" is better than "4 D", with a RelativeDateTimeFormatter and a spellOut units style. "Monday" is better than "Mon", accessing the weekdaySymbols from a Calendar. Some useful links: Relative Date Time Formatter: https://developer.apple.com/documentation/foundation/relativedatetimeformatter Units Style: https://developer.apple.com/documentation/foundation/relativedatetimeformatter/unitsstyle-swift.enum/spellout Weekday symbols: https://developer.apple.com/documentation/foundation/calendar/weekdaysymbols

Tip for abbreviations. Something like "3h 24m" will be read by VoiceOver as "3 h 24 meters". Formatters can help. DateComponentsFormatter with a "spellOut" units style will give you a more suitable label: "three hours, twenty-four minutes" Example code in the image: ```swift let dailyAverageLabel = UILabel() let abbreviatedReadableFormatter = DateComponentsFormatter() abbreviatedReadableFormatter.allowedUnits = [.hour, .minute] abbreviatedReadableFormatter.unitsStyle = .spellOut let abbreviatedReadableDuration = abbreviatedReadableFormatter.string(from: 12240) dailyAverageLabel.accessibilityLabel = abbreviatedReadableDuration ``` Some useful links: * Date Components Formatter: * Units Style: By the way! Formatters are also great for localisation.
Accessibility labels are not just for VoiceOver. If you tweak how they sound by changing spelling, adding spaces, etc. you could be making the experience worse for Voice Control and Braille display users. Attributed accessibility labels can help.

With the attribute accessibilitySpeechPunctuation, you can ask VoiceOver to speak any punctuation marks in your attributed accessibility label, if that is what you want. Good for code snippets?

accessibilitySpeechSpellOut asks VoiceOver to speak the sequence of characters. Can be useful for things like promo/reference/authentication codes, phone numbers... it makes more sense to announce each character rather than words and big numbers. Example code in the image: ```swift let codeLabel = UILabel() let attributedLabel = NSAttributedString( string: "BAC1234567D", attributes: [.accessibilitySpeechSpellOut: true] ) title.accessibilityAttributedLabel = attributedLabel ```

accessibilitySpeechPitch lets you emphasise something changing VoiceOver's pitch. The value goes from 0.0 to 2.0. The default is 1.0. Twitter could change pitch to read hashtags, for example, avoiding repetition but still signalling they're there.

accessibilitySpeechIPANotation is useful for indicating how foreign words are pronounced. It really annoys me to hear the word paella constantly mispronounced 😁. You could also specify language, but this way, VoiceOver won't change its voice. Example code in the image: ```swift let recipeNameLabel = UILabel() let attributedLabel = NSAttributedString( string: "Paella", attributes: [.accessibilitySpeechIPANotation: "pɑːˈeɪə"] ) recipeNameLabel.accessibilityAttributedLabel = attributedLabel ```

accessibilitySpeechIPANotation is sometimes handy in English where a word is spelled the same but pronounced differently depending of the context. Some examples are: live, read... Or you may want to correct how VoiceOver pronounces your app's name! Example code in the image: ```swift let liveNewsChannelView = UIView() let attributedLabel = NSMutableAttributedString(string: "24 hour news channel. ") attributedLabel.append(NSAttributedString(string: "Live",attributes: [.accessibilitySpeechIPANotation: "laɪv"])) liveNewsChannelView.accessibilityAttributedLabel = attributedLabel ```
An interesting speech attribute for attributed accessibility labels is accessibilitySpeechIPANotation that lets you specify how VoiceOver should pronounce a label with the International Phonetic Alphabet (IPA) notation. https://developer.apple.com/documentation/foundation/nsattributedstring/key/accessibilityspeechipanotation

With attributed accessibility labels, your app could now, for example, greet your users in different languages. Note that it will change to the voice of the corresponding language you are switching to. Example code in the image: ```swift let greetingLessonView = UIView() let bcp47LanguageCode = "es-Es" let translatedPhrase = "¡Buenos días! " let attributedLabel = NSMutableAttributedString(string: translatedPhrase,attributes: [.accessibilitySpeechLanguage: bcp47LanguageCode]) attributedLabel.append(NSAttributedString(string: "Means: good morning!")) greetingLessonView.accessibilityAttributedLabel = attributedLabel ```
Attributed accessibility labels are a thing! They'll let you specify (for the whole accessibility label or a portion of it) VoiceOver's language, to read punctuation marks, spell it out, correct the pronunciation, or even change the pitch. @RobRWAPP has a very detailed blog post explaining each one of these attributes: https://mobilea11y.com/blog/attributed-accessibility-labels/ And here's Apple's official documentation for them: https://developer.apple.com/documentation/uikit/speech-attributes-for-attributed-strings
Believe it or not, one of the most common accessibility pitfalls I see in iOS apps, is forgetting to configure a suitable accessibility label for buttons with just an image (no title), resulting in VoiceOver saying just: "button". Why for buttons with just an image? If it has a title, the accessibility label gets inferred from it. So here's one that should be very easy for you to find and fix in your app. No more apps that just say: button, button, button, button...! If you are looking for the best explanation on what makes, not good, but great accessibility labels, I really recommend “Writing Great Accessibility Labels” by @jordyn2493 at WWDC. The difference between someone using/loving/deleting your app. https://developer.apple.com/videos/play/wwdc2019/254/
Showing 211-225 of 230 posts