-
Prepare your app for Accessibility Nutrition Labels
Learn how to prepare your app for Accessibility Nutrition Labels by supporting essential accessibility features. Discover how you can enhance interaction methods like VoiceOver and Voice Control by properly configuring accessibility labels, traits, and values for custom controls and gestures. Find out how you can support larger text sizes using Dynamic Type, and prevent content truncation with flexible layouts. And learn how to make your app design more inclusive by adopting Dark Mode, responding to preferences like Differentiate Without Color, and ensuring sufficient contrast.
関連する章
- 0:01 - Welcome
- 2:18 - Interaction methods
- 18:04 - Larger text
- 26:27 - Color
- 32:55 - Next steps
リソース
- Overview of Accessibility Nutrition Labels
- Accessibility
- Learn more about designing for accessibility
関連ビデオ
WWDC25
WWDC24
-
このビデオを検索
-
-
6:39 - Add descriptive accessibility labels
// Add descriptive accessibility labels // SwiftUI Image(landmark.backgroundImageName) .accessibilityLabel("Vibrant cherry blossoms frame a snow-capped mountain rising in the background.") // UIKit let imageView = UIImageView(image: UIImage(named: landmark.backgroundImageName)) imageView.isAccessibilityElement = true imageView.accessibilityLabel = "Vibrant cherry blossoms frame a snow-capped mountain rising in the background." -
7:43 - Add alternate labels for Voice Control
// Add alternate labels for Voice Control Button { addFavorite() } label: { Image(systemName: "heart") } .accessibilityLabel("Favorite") .accessibilityInputLabels(["Favorite", "Heart", "Like", "Love"]) -
8:23 - Set accessibility traits to match an element’s role
// Set accessibility traits to match an element’s role // SwiftUI Text("Accessibility Nutrition Labels") .font(.title) .accessibilityAddTraits(.isHeader) // UIKit let label = UILabel() /*...*/ label.accessibilityTraits = .header -
9:29 - Implement custom adjustable behavior
// Implement custom adjustable behavior // SwiftUI MySliderView() .accessibilityAdjustableAction { direction in switch direction { case .increment: // Increase value case .decrement: // Decrease value } } // UIKit class MySliderView: UIView { override var accessibilityTraits: UIAccessibilityTraits { get { .adjustable } set {} } override func accessibilityIncrement() { /* Increase value */ } override func accessibilityDecrement() { /* Decrease value */ } } -
9:54 - Set an accessibility value
// Set an accessibility value // SwiftUI MyView() .accessibilityValue("Value") // UIKit myView.accessibilityValue = "Value" -
12:26 - Hide decorative images from VoiceOver
// Hide decorative images from VoiceOver // SwiftUI Image(decorative: landmark.thumbnailImageName) /* or */ Image(landmark.thumbnailImageName) .accessibilityHidden(true) // UIKit imageView.isAccessibilityElement = false -
12:59 - Combine elements to improve VoiceOver navigation
// Combine elements to improve VoiceOver navigation HStack { HStack { Text("SFO") Image(systemName: "airplane.departure") .accessibilityLabel("to") Text("HND") } .font(.title3.bold()) Spacer() VStack { Text("Arriving in") Text("15").font(.title.bold()) Text("minutes") } } .accessibilityElement(children: .combine) -
15:03 - Make a custom component accessible
// Make a custom component accessible HStack { ForEach(1...5, id: \.self) { index in Image(systemName: index <= Int(badgeProgress.rating) ? "star.fill" : "star") } } .accessibilityElement() .accessibilityLabel("Rating") .accessibilityValue("\(Int(badgeProgress.rating))") .accessibilityAdjustableAction { direction in switch direction { case .increment: badgeProgress.rating = min(5, badgeProgress.rating + 1) case .decrement: badgeProgress.rating = max(0, badgeProgress.rating - 1) } } -
15:37 - Make a custom component accessible
// Make a custom component accessible HStack { ForEach(1...5, id: \.self) { index in Image(systemName: index <= Int(badgeProgress.rating) ? "star.fill" : "star") } } .accessibilityRepresentation { Slider(value: $badgeProgress.rating, in: 0...5, step: 1.0) { Text("Rating") } } -
16:30 - Add accessibility traits for tap gestures
// Add accessibility traits for tap gestures HStack { Text("Learn more") Image(systemName: "chevron.forward") } .foregroundColor(.blue) .onTapGesture { /*...*/ } .accessibilityAddTraits(.isButton) -
17:13 - Add accessibility actions for custom gestures
// Add accessibility actions for custom gestures Image(landmark.backgroundImageName) .accessibilityLabel(landmark.imageDescription ?? landmark.name) .onTapGesture(count: 2) { modelData.addFavorite(landmark) } .accessibilityAction(named: "Favorite") { modelData.addFavorite(landmark) } -
20:07 - Adopt system text styles for automatic scaling
// Adopt system text styles for automatic scaling // SwiftUI Text("Hello World") .font(.body) // UIKit label.font = UIFont.preferredFont(forTextStyle: .body) label.adjustsFontForContentSizeCategory = true -
20:33 - Make custom fonts scale proportionally with system font styles
// Make custom fonts scale proportionally with system font styles // SwiftUI Text("Hello World") .font(.custom("MyFont", size: 17, relativeTo: .body)) // UIKit guard let customFont = UIFont(name: "MyFont", size: 17) else { return } label.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: customFont) label.adjustsFontForContentSizeCategory = true -
22:57 - Embed content in ScrollView to avoid truncation
// Embed content in ScrollView to avoid truncation ScrollView { VStack(spacing: 24) { EarnedBadgeView(badge: badge) Text("Congratulations!") Text("...") } } .scrollBounceBehavior(.basedOnSize) .safeAreaBar(edge: .bottom) { VStack { Button("Share badge") { } Button("Close") { } } } -
25:17 - Set number of lines to 0 to avoid truncation
// Set number of lines to 0 to avoid truncation // SwiftUI Text("Some longer text that takes up multiple lines.") .lineLimit(nil) // UIKit label.numberOfLines = 0 -
26:53 - Check the differentiate without color setting
// Check the differentiate without color setting // SwiftUI @Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor // UIKit let differentiateWithoutColor = UIAccessibility.shouldDifferentiateWithoutColor NotificationCenter.default.addObserver(self, selector: #selector(diffWithoutColorDidChange), name: UIAccessibility.differentiateWithoutColorDidChangeNotification, object: nil) -
27:42 - Differentiate without color alone in Swift Charts
// Differentiate without color alone in Swift Charts Chart(visitorData) { data in LineMark( x: .value("Month", data.month), y: .value("Visitors", data.numVisitors) ) .foregroundStyle(by: .value("Landmark", data.landmark)) PointMark( x: .value("Month", data.month), y: .value("Visitors", data.numVisitors) ) .foregroundStyle(by: .value("Landmark", data.landmark)) .symbol(by: .value("Landmark", data.landmark)) } -
30:36 - Check the preference for Reduce Transparency
// Check the preference for Reduce Transparency // SwiftUI @Environment(\.accessibilityReduceTransparency) var reduceTransparencyEnabled // UIKit let reduceTransparencyEnabled = UIAccessibility.isReduceTransparencyEnabled NotificationCenter.default.addObserver(self, selector: #selector(reduceTransparencyDidChange), name: UIAccessibility.reduceTransparencyStatusDidChangeNotification, object: nil) -
31:22 - Check the preference for Increase Contrast
// Check the preference for Increase Contrast // SwiftUI @Environment(\.colorSchemeContrast) var colorSchemeContrast // UIKit let increaseContrastEnabled = view.traitCollection.accessibilityContrast == .high registerForTraitChanges([UITraitAccessibilityContrast.self], action: #selector(accessibilityContrastDidChange))
-