One of my blind users reached out to me after they updated to iPadOS 18. I have a button that is used to mark/unmark a favorite location.
He said that he could still tell the favorite status via the label and hint, but VoiceOver was always saying that the switch button is off.
I'm able to recreate this on my iPad as well. The documentation for .isToggle is completely blank.
Basically with iPadOS 17 adding the .isToggle trait makes VoiceOver state that my button is a toggle.
With iPadOS 18 adding the .isToggle trait makes VoiceOver state that my button is a toggle AND try to state its current value. I don't know if this is intentional or a bug.
Button {
showFavActions()
} label: {
Image(systemName: SFSymbolShortcut.star.rawValue)
.symbolVariant(weatherData.currentlyFavIndex == nil ? .none : .fill)
}
.buttonStyle(.plain)
.accessibilityLabel(Text(weatherData.currentlyFavIndex == nil ? "Not a favorite location." : "Favorite location."))
.accessibilityHint(Text(weatherData.currentlyFavIndex == nil ? "Add to favorites." : "Remove from favorites."))
.accessibilityInputLabels(["Favorite"])
.accessibilityAddTraits(.isToggle) // iOS 17
I think I have a way to address this.
I changed the accessibilityLabel to be "Favorite Button" and added accessibilityValue with the current value.
After that VoiceOver is no longer always saying the toggle is off.
Button {
showFavActions()
} label: {
Image(systemName: SFSymbolShortcut.star.rawValue)
.symbolVariant(weatherData.currentlyFavIndex == nil ?
.none : .fill)
}
.buttonStyle(.plain)
.accessibilityLabel(Text("Favorite Button"))
.accessibilityHint(Text(weatherData.currentlyFavIndex == nil ?
"Add to favorites." :
"Remove from favorites."))
.accessibilityInputLabels(["Favorite"])
.accessibilityAddTraits(.isToggle) // iOS 17
.accessibilityValue(weatherData.currentlyFavIndex == nil ?
"Not a favorite location." :
"Favorite location.")