Logo for tanaschita.com

Introduction to supporting VoiceOver in SwiftUI

Learn how to use different accessibility modifiers in SwiftUI.

updated on 09 Sep 2024 · 8 min read

Making an app accessible is crucial for ensuring that all users, including those with disabilities, can enjoy a seamless experience. For instance, users who rely on assistive technologies like VoiceOver should be able to interact with our apps without needing to see the screen.

SwiftUI simplifies the process of adding accessibility to our apps by automatically setting accessibility labels and values for standard views like navigation views, lists, text fields, sliders, and buttons. However, there are scenarios where additional work is needed to enhance the user experience, particularly when using custom views, images, or image-only buttons.

Let's dive into a practical example.

Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE

Finding VoiceOver issues

The first step in improving accessibility is to identify potential VoiceOver issues. We can do this by either activating VoiceOver on our device or by using Xcode’s Accessibility Inspector.

To open the Accessibility Inspector, select Xcode > Open Developer Tool > Accessibility Inspector in Xcode's menu.

The Accessibility Inspector allows us to navigate through different view elements and listen to how VoiceOver reads them. This helps us assess whether the accessibility values are providing a good user experience.

While the Accessibility Inspector is a useful development tool, it doesn’t replace the need to test accessibility features with VoiceOver on an actual device. To learn how to use VoiceOver, check out this guide on VoiceOver gestures for iOS.

Example: Improving accessibility of an image-only button

When using buttons with titles, SwiftUI automatically assigns appropriate accessibility values.

Button("Cancel", action: {
// Cancel button action
})

In this example, VoiceOver will correctly read Cancel Button to the user, requiring no further action on our part.

However, the situation changes when using image-only buttons. SwiftUI will still recognize the element as a button, but without an appropriate label, VoiceOver will only announce Button which is unhelpful for users who cannot see the image.

To address this, we can use the accessibilityLabel(_:) modifier to provide a descriptive label for the button:

Button("", action: {
// Favorites button action
})
.buttonStyle(ImageButtonStyle(systemImage: "heart"))
.accessibilityLabel("Favorites")

With this label in place, VoiceOver will now read Favorites Button offering much clearer guidance to the user.

Besides accessibilityLabel(_:), SwiftUI provides other accessibility modifiers to improve accessibility.

Example: Improving accessibility when using onTapGesture

When using onTapGesture in SwiftUI, the view doesn't automatically gain accessibility traits, which can make it invisible to VoiceOver users. To ensure accessibility, we need to add appropriate labels and traits.

Consider an example where an image triggers an action when tapped:

Image(systemName: "heart")
.onTapGesture {
favoriteItem()
}

In its current form, VoiceOver users won't know this image is interactive. We can improve accessibility by adding a label and traits:

Image(systemName: "star")
.onTapGesture {
favoriteItem()
}
.accessibilityLabel("Favorite")
.accessibilityAddTraits(.isButton)

Example: Improving accessibility by combining views to one accessibility element

Sometimes, multiple views on the screen represent a single piece of information or an action. For example, a label and an icon together might indicate the same function. By default, VoiceOver will read each view separately, which can be confusing. To improve accessibility, we can combine these views into one accessibility element.

Consider this example with a text label and an image:

HStack {
Image(systemName: "heart")
Text("Favorite")
}

By default, VoiceOver will read "Star" and "Favorite" separately. We can improve this by combining them into a single accessible element:

HStack {
Image(systemName: "star")
Text("Favorite")
}
.accessibilityElement(children: .combine)
.accessibilityLabel("Favorite")

Commonly used accessibility modifiers

To summarize, here is a list of the commonly used accessibility modifiers:

Sponsorship logo
Preparing for a technical iOS job interview
Preparing for a technical iOS Job Interview with over 300 questions & answers. Covering Swift & Objective-C, SwiftUI & UIKit, Combine, HTTP Networking, iOS File System, Core Data, Concurrency with async/await, Security, Automated Testing, Dependency Management, AI & Machine Learning and more.
LEARN MORE
Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE
Sponsorship logo
Become a sponsor of tanaschita.com
By publishing an article on different iOS topics every week, tanaschita.com is constantly growing in the developer community and may provide a great audience for you as a sponsor.
CLICK TO LEARN MORE

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

accessibility

swiftui

ios

Overview on Accessibility Nutrition Labels for iOS development

Get an overview of what Accessibility Nutrition Labels are and how to support them.

28 Jul 2025 · 5 min read

Latest articles and tips

© 2026 tanaschita.com

Privacy policy

Impressum