Ios accessibility
Skill almasumdev/awesome-ios-agent-skills/.github/skills/ui/ios-accessibility
Curated agent skills, conventions, and workflows for building iOS apps (Swift, SwiftUI, UIKit) with AI coding agents.
npx -y skills add almasumdev/awesome-ios-agent-skills --skill ios-accessibilityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Expert guidance on iOS accessibility — VoiceOver, accessibility labels/values/traits, Dynamic Type, reduce motion, contrast, and testing. Use whenever UI is being built or reviewed.
SKILL.md
4.1 KB, as published. Nobody here has run it
iOS Accessibility
Instructions
Accessibility is a design requirement, not a polish pass. Every interactive element needs a label, a reachable hit target, scalable text, and a path through VoiceOver.
1. VoiceOver Labels, Values, Hints
SwiftUI synthesizes labels from visible Text. Override when the visual is an icon or when extra context helps:
Button {
toggleFavorite()
} label: {
Image(systemName: isFavorite ? "star.fill" : "star")
}
.accessibilityLabel(isFavorite ? "Unfavorite" : "Favorite")
.accessibilityValue(isFavorite ? "On" : "Off")
.accessibilityHint("Double-tap to toggle favorite state.")
Group related views so VoiceOver reads them as one element:
HStack {
Image(systemName: "thermometer")
Text("72")
Text("°F")
}
.accessibilityElement(children: .combine)
.accessibilityLabel("Temperature: 72 degrees Fahrenheit")
2. Traits
Traits teach VoiceOver how to treat a view:
TitleLabel()
.accessibilityAddTraits(.isHeader)
LoadingSpinner()
.accessibilityAddTraits(.updatesFrequently)
Button("Delete", role: .destructive) {}
Common traits: .isButton, .isHeader, .isSelected, .isLink, .updatesFrequently, .playsSound, .isToggle.
3. Dynamic Type
Use system styles (.body, .headline, .caption) — they scale automatically. Never hardcode .system(size:) for UI text.
Text("Hello")
.font(.body)
.lineLimit(nil) // allow wrapping
.fixedSize(horizontal: false, vertical: true)
Preview at extreme sizes:
#Preview("XXL Dynamic Type") {
ArticleRow(article: .sample)
.environment(\.dynamicTypeSize, .accessibility5)
}
Use ViewThatFits to pick a layout that survives larger type:
ViewThatFits(in: .horizontal) {
HStack { Text(title); Spacer(); Text(subtitle) }
VStack(alignment: .leading) { Text(title); Text(subtitle) }
}
4. Motion & Transparency
Respect user preferences:
@Environment(\.accessibilityReduceMotion) private var reduceMotion
@Environment(\.accessibilityReduceTransparency) private var reduceTransparency
var body: some View {
content
.animation(reduceMotion ? nil : .spring, value: isExpanded)
.background(reduceTransparency ? Color(.systemBackground) : .thinMaterial)
}
5. Contrast & Color
- Never rely on color alone — pair with icon, text, or shape.
- Use
.foregroundStyle(.primary/.secondary/.tertiary)and semantic colors, not raw hex. - Respect
\.accessibilityDifferentiateWithoutColorand\.accessibilityInvertColors.
Label("Error", systemImage: "exclamationmark.triangle")
.foregroundStyle(.red)
.symbolRenderingMode(.hierarchical)
6. Hit Targets
Minimum tap target is 44×44 points. Enlarge hit areas without moving the visual:
Button(action: openMenu) {
Image(systemName: "ellipsis")
}
.frame(minWidth: 44, minHeight: 44)
.contentShape(Rectangle())
7. Testing
- Turn on the Accessibility Inspector in Xcode and audit every screen.
- Run VoiceOver on a device: swipe-right through every element to verify order and labels.
- In XCUITest, prefer
app.buttons["favorite"]using the identifier, not the label.
Button(...)
.accessibilityIdentifier("favorite")
8. Form Accessibility
Bind labels to controls so VoiceOver reads them together:
Toggle(isOn: $notificationsOn) {
Text("Notifications")
Text("Get updates about new articles").font(.caption)
}
Checklist
- Every interactive element has a label and, where useful, a hint.
- Icons without visible text have
.accessibilityLabel. - Text uses semantic fonts; screens survive
.accessibility5Dynamic Type. - Animations check
accessibilityReduceMotion. - Color is never the sole carrier of meaning.
- Tap targets are ≥ 44×44.
- Accessibility identifiers are set for elements tested in UI tests.