This skill should be used when the user asks to "add VoiceOver support", "implement Dynamic Type", "check color contrast", "ensure WCAG compliance", "audit accessibility", "make app accessible", or needs guidance on iOS accessibility patterns and inclusive design.
From ios-dev-toolkitnpx claudepluginhub nbkm8y5/claude-plugins --plugin ios-dev-toolkitThis skill uses the workspace's default tool permissions.
generated/AccessibilityAuditor.swiftgenerated/AccessibilityExtensions.swiftgenerated/AccessibleButton.swiftgenerated/AccessibleCard.swiftgenerated/AccessibleLabel.swiftgenerated/AccessibleList.swiftgenerated/AccessibleTextField.swiftgenerated/ColorContrastAuditor.swiftgenerated/DynamicTypeAuditor.swiftgenerated/KeyboardNavigationAuditor.swiftgenerated/VoiceOverAuditor.swiftreferences/accessibility_patterns.mdreferences/wcag_guidelines.mdscripts/generate_accessibility_audit.pyscripts/generate_accessible_components.pySearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides implementation of event-driven hooks in Claude Code plugins using prompt-based validation and bash commands for PreToolUse, Stop, and session events.
Complete accessibility infrastructure for building inclusive iOS applications that work for everyone.
Use this skill when:
python scripts/generate_accessibility_audit.py
This generates:
Total: 888 lines of audit infrastructure
python scripts/generate_accessible_components.py
This generates:
Total: 799 lines of accessible components
Running both scripts generates 1,687 lines of production-ready accessibility infrastructure.
import SwiftUI
struct ContentView: View {
@StateObject private var auditor = AccessibilityAuditor()
var body: some View {
VStack {
MyAppContent()
Button("Run Accessibility Audit") {
Task {
let result = await auditor.runAudit(on: MyAppContent())
// Handle results
}
}
}
.sheet(item: $auditor.lastAuditResult) { result in
AccessibilityAuditResultView(result: result)
}
}
}
import SwiftUI
struct LoginForm: View {
@State private var email = ""
@State private var password = ""
var body: some View {
VStack(spacing: 16) {
// Accessible text field with proper labeling
AccessibleTextField(
label: "Email",
text: $email,
placeholder: "Enter your email",
hint: "Your email address for login",
isRequired: true,
keyboardType: .emailAddress,
textContentType: .emailAddress
)
// Secure field for password
AccessibleTextField(
label: "Password",
text: $password,
placeholder: "Enter password",
hint: "Your account password",
isRequired: true,
isSecure: true,
textContentType: .password
)
// Accessible button
AccessibleButton(
title: "Sign In",
action: signIn,
icon: "arrow.right.circle.fill",
hint: "Sign in to your account"
)
}
.padding()
}
func signIn() {
// Sign in logic
}
}
import SwiftUI
struct ColoredText: View {
var body: some View {
Text("Important Message")
.foregroundColor(.blue)
.background(Color.white)
.checkColorContrast(
foreground: .blue,
background: .white,
level: .aa,
isLargeText: false
)
}
}
import SwiftUI
struct ScalableView: View {
@ScaledMetric var spacing: CGFloat = 16
@ScaledMetric var iconSize: CGFloat = 24
var body: some View {
HStack(spacing: spacing) {
Image(systemName: "star.fill")
.font(.system(size: iconSize))
Text("Content")
.font(.body) // Automatically scales
}
}
}
import SwiftUI
struct FocusableForm: View {
@FocusState private var focusedField: Field?
enum Field: Hashable {
case firstName
case lastName
case email
}
@State private var firstName = ""
@State private var lastName = ""
@State private var email = ""
var body: some View {
VStack(spacing: 16) {
TextField("First Name", text: $firstName)
.focused($focusedField, equals: .firstName)
.focusAccessibility(
identifier: .firstName,
focusedField: $focusedField,
fields: [.firstName, .lastName, .email]
)
TextField("Last Name", text: $lastName)
.focused($focusedField, equals: .lastName)
.focusAccessibility(
identifier: .lastName,
focusedField: $focusedField,
fields: [.firstName, .lastName, .email]
)
TextField("Email", text: $email)
.focused($focusedField, equals: .email)
.focusAccessibility(
identifier: .email,
focusedField: $focusedField,
fields: [.firstName, .lastName, .email]
)
}
.onAppear {
focusedField = .firstName
}
}
}
Enhance existing components with accessibility:
// Add accessibility to currency input
CurrencyInputField(value: $amount)
.accessibilityLabel("Loan amount")
.accessibilityHint("Enter the loan amount in dollars")
.accessibilityValue(formatCurrency(amount))
// Add accessibility to percentage input
PercentageInputField(value: $rate)
.accessibilityLabel("Interest rate")
.accessibilityHint("Enter the annual interest rate")
.accessibilityValue("\\(rate) percent")
Make multi-step forms fully accessible:
// Add VoiceOver support to form steps
FormCoordinatorView(
coordinator: formCoordinator,
onComplete: handleCompletion
)
.accessibilityLabel("Loan application, step \\(coordinator.currentStepIndex + 1) of \\(coordinator.steps.count)")
.accessibilityHint("Complete this step to continue")
// Accessible form fields
TextFormField(label: "Property Address", text: $address)
.accessibilityLabel("Property address, required")
.accessibilityHint("Enter the full address of the property")
Make financial data accessible:
// Accessible currency display
AccessibleCurrencyLabel(
amount: monthlyPayment,
label: "Monthly Payment"
)
// Accessible percentage display
AccessiblePercentageLabel(
value: interestRate,
label: "Interest Rate"
)
// Accessible chart description
Chart(amortizationData) { entry in
BarMark(x: .value("Year", entry.year), y: .value("Balance", entry.balance))
}
.accessibilityLabel("Loan balance over time")
.accessibilityValue("Shows how your loan balance decreases each year")
Ensure exported PDFs are accessible:
// Generate accessible PDF with proper structure
let pdf = generatePDF()
pdf.accessibilityLabel = "Loan Application Report"
pdf.accessibilityStructure = .document
For detailed patterns and guidelines, refer to:
references/accessibility_patterns.md)Comprehensive patterns including:
When to read: When implementing accessibility for specific UI patterns or components.
references/wcag_guidelines.md)iOS-specific WCAG 2.1 compliance guide including:
When to read: When ensuring WCAG compliance or preparing for App Store submission.
Use the accessible components provided by this skill rather than building from scratch.
// ❌ Bad
Button("Submit") { }
// ✅ Good
Button("Submit Application") { }
.accessibilityLabel("Submit loan application")
.accessibilityHint("Submits your application for review")
// ❌ Bad - Each element read separately
HStack {
Image(systemName: "star.fill")
Text("4.5")
Text("Rating")
}
// ✅ Good - Combined into single element
HStack {
Image(systemName: "star.fill")
Text("4.5")
Text("Rating")
}
.accessibilityElement(children: .combine)
.accessibilityLabel("Rating: 4.5 stars")
// ❌ Bad - Fixed size
Text("Content").font(.system(size: 16))
// ✅ Good - Scalable
Text("Content").font(.body)
// Buttons
.accessibilityAddTraits(.isButton)
// Headers
.accessibilityAddTraits(.isHeader)
// Selected items
.accessibilityAddTraits(.isSelected)
Toggle("Notifications", isOn: $enabled)
.accessibilityLabel("Notifications")
.accessibilityValue(enabled ? "Enabled" : "Disabled")
if let error = validationError {
Label(error, systemImage: "exclamationmark.circle.fill")
.foregroundColor(.red)
.accessibilityLabel("Error: \\(error)")
}
if isLoading {
ProgressView()
.accessibilityLabel("Loading loan details")
}
// Automatically adapts to light/dark mode
Text("Content")
.foregroundColor(.primary)
.background(Color(.systemBackground))
struct AccessibleLoanForm: View {
@State private var loanAmount = ""
@State private var interestRate = ""
@FocusState private var focusedField: Field?
enum Field: Hashable {
case amount, rate
}
var body: some View {
Form {
Section {
AccessibleTextField(
label: "Loan Amount",
text: $loanAmount,
placeholder: "$0",
hint: "Enter the amount you want to borrow",
isRequired: true,
keyboardType: .decimalPad
)
AccessibleTextField(
label: "Interest Rate",
text: $interestRate,
placeholder: "0%",
hint: "Enter the annual interest rate",
isRequired: true,
keyboardType: .decimalPad
)
} header: {
AccessibleSectionHeader(
title: "Loan Details",
subtitle: "Enter your loan information"
)
}
Section {
AccessibleButton(
title: "Calculate Payment",
action: calculatePayment,
icon: "dollarsign.circle.fill",
hint: "Calculates your monthly payment"
)
}
}
.navigationTitle("Loan Calculator")
}
func calculatePayment() {
// Calculation logic
}
}
struct AccessibleCalculationHistoryList: View {
let calculations: [Calculation]
var body: some View {
List {
ForEach(calculations) { calc in
AccessibleListRow(
label: "\\(calc.title), \\(calc.date)",
hint: "View calculation details",
action: { viewDetails(calc) }
) {
VStack(alignment: .leading, spacing: 8) {
Text(calc.title)
.font(.headline)
AccessibleCurrencyLabel(
amount: calc.amount,
label: "Amount"
)
AccessibleDateLabel(
date: calc.date,
label: "Date"
)
}
}
}
.onDelete(perform: deleteCalculations)
}
.navigationTitle("History")
}
func viewDetails(_ calc: Calculation) { }
func deleteCalculations(at offsets: IndexSet) { }
}
struct AccessibleLoanChart: View {
let amortizationData: [AmortizationEntry]
var body: some View {
Chart(amortizationData) { entry in
BarMark(
x: .value("Year", entry.year),
y: .value("Balance", entry.balance)
)
}
.accessibilityLabel("Loan balance over time")
.accessibilityValue(chartDescription)
}
private var chartDescription: String {
let years = amortizationData.count
let startBalance = amortizationData.first?.balance ?? 0
let endBalance = amortizationData.last?.balance ?? 0
return """
Chart showing loan balance decreasing from \
\\(formatCurrency(startBalance)) to \
\\(formatCurrency(endBalance)) over \\(years) years
"""
}
}
Before releasing your app, verify:
For App Store approval, ensure:
After running the generation scripts, you'll have:
Copy the generated files to your Xcode project and start using them immediately. All components are production-ready with full documentation.
This skill provides everything needed to build fully accessible iOS applications:
Use this skill to make your iOS apps accessible to everyone, meet App Store requirements, and provide an excellent experience for all users.