26 ios hig review
Skill FluxonLab/Skillry/plugins/mobile-desktop/skills/26-ios-hig-review
Use when you need to review iOS interfaces against platform conventions, navigation, accessibility, and touch ergonomics.From its SKILL.md
npx -y skills add FluxonLab/Skillry --skill 26-ios-hig-reviewAssembled 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.
- 2 stars2 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.
SKILL.md
9.5 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it
iOS HIG Review
Purpose
Audit an iOS interface (UIKit or SwiftUI) against Apple's Human Interface Guidelines: safe-area layout, Dynamic Type, SF Symbols usage, haptic feedback, dark mode, tap-target sizing, navigation paradigm, and VoiceOver support. The output is a prioritized set of findings, each citing the relevant HIG area and a concrete code fix, ranked by App Store submission risk. The review reads source or screenshots only and never triggers Xcode builds or TestFlight uploads.
When to use
- A SwiftUI or UIKit screen needs review before App Store submission.
- Design or code review for an iOS-specific feature (sheets, navigation, widgets, Live Activities).
- An App Store rejection cited HIG violations and a root-cause analysis is needed.
- An accessibility audit is requested for VoiceOver, Dynamic Type, or Reduce Motion compliance.
When not to use
- The app is Android-only — use
android-material-review. - The review is purely about business logic or backend integration — use
mobile-app-review. - The design exists in a design tool only with no code to audit — this skill needs source or screenshots.
Procedure
- Identify the UI framework and deployment target. Confirm SwiftUI, UIKit, or hybrid. Note the minimum iOS version — HIG expectations differ across iOS 15 to 18 (for example NavigationStack and the Dynamic Island land in iOS 16 and later).
- Check safe area and layout margins. Verify
.safeAreaInset,safeAreaLayoutGuide, or.ignoresSafeAreausage is intentional. Content under the notch, Dynamic Island, or home indicator must be deliberate and remain readable. - Audit Dynamic Type support. All text should use a text style —
.font(.body)or.font(.headline)in SwiftUI, orUIFont.preferredFont(forTextStyle:)in UIKit, or a custom font viarelativeTo:. Confirm labels do not truncate at accessibility sizes; use.fixedSize(horizontal: false, vertical: true)where needed. - Review tap-target sizes. Every interactive element must be at least 44x44 pt. Wrap small icon-only buttons in
.frame(minWidth: 44, minHeight: 44)or add.contentShape(Rectangle())to extend the hit area. - Check SF Symbols usage. Verify symbol names exist on the deployment target (confirm in the SF Symbols app). Prefer
.symbolRenderingModeand.foregroundStyleover tint hacks; multicolor symbols need.renderingMode(.original); tab-bar symbols need the.fillvariant. - Review haptic feedback.
UIImpactFeedbackGeneratorandUINotificationFeedbackGenerator(or SwiftUI.sensoryFeedback) should mark meaningful state changes, not decorate animations. Call.prepare()before.impactOccurred()to avoid first-fire latency. - Audit dark mode support. Replace hardcoded
UIColor(red:...)andColor(red:...)with semantic colors (Color(.systemBackground),.label,.secondaryLabel). Confirm asset-catalog images have dark variants. - Review the navigation paradigm. Use
NavigationStack(iOS 16 and later) instead of the deprecatedNavigationView. Modal sheets are for self-contained tasks, not drill-down. The back-button label should reflect the parent title, not a generic "Back". - Check sheet and presentation style. Confirm
.sheet,.fullScreenCover, and.presentationDetentsare appropriate; destructive actions in a sheet require explicit confirmation. - Review accessibility annotations. Confirm
.accessibilityLabel,.accessibilityHint, and.accessibilityValueon custom controls; mark decorative images.accessibilityHidden(true); verifyUIAccessibility.isReduceMotionEnabledis respected for non-essential animation. - Summarize findings with HIG section references and severity.
Concrete checks
Layout and type:
- Content does not underlap the notch, Dynamic Island, or home indicator unintentionally.
- All text uses a text style and scales with Dynamic Type.
- No truncation at the largest accessibility sizes.
Touch and symbols:
- Every interactive element is at least 44x44 pt.
- SF Symbol names are valid for the deployment target with the correct rendering mode.
- Tab-bar symbols use the
.fillvariant.
Color and motion:
- No hardcoded colors that break dark mode; asset catalog has dark variants.
- Haptics mark meaningful feedback and call
.prepare()first. - Non-essential animation respects Reduce Motion.
Navigation and accessibility:
NavigationStackis used on iOS 16 and later; modals are for tasks, not drill-down.- The back-button label reflects the parent screen.
- Custom controls have VoiceOver labels and hints; decorative images are hidden.
Info.plistprivacy usage strings are present and accurate.
Commands
# --- Dynamic Type ---
# hardcoded fonts that break Dynamic Type
rg -n 'Font.system\(size:|UIFont.systemFont\(ofSize:|\.font\(.system\(size:' .
# --- dark mode ---
# hardcoded colors that break dark mode
rg -n 'UIColor\(red:|Color\(red:|UIColor\(white:|#[0-9a-fA-F]{6}' .
# --- navigation ---
# deprecated NavigationView (should be NavigationStack on iOS 16+)
rg -n 'NavigationView\b' .
# custom back buttons that may drop the parent title
rg -n 'navigationBarBackButtonHidden|\.backButtonTitle' .
# --- SF Symbols / tap targets ---
# small icon-only buttons — verify 44pt hit area nearby
rg -n 'Image\(systemName:' . | head -40
# tab-bar symbols missing the fill variant
rg -n 'TabItem|tabItem' . | head
# --- haptics ---
# haptic generators and whether prepare() is called
rg -n 'FeedbackGenerator|impactOccurred|sensoryFeedback|\.prepare\(\)' . | head
# --- accessibility ---
# accessibility annotations present on custom controls?
rg -n 'accessibilityLabel|accessibilityHint|accessibilityHidden' . | head
# Reduce Motion respected?
rg -n 'isReduceMotionEnabled|accessibilityReduceMotion' .
# --- privacy ---
# Info.plist privacy usage strings
rg -n 'NSCameraUsageDescription|NSMicrophoneUsageDescription|NSLocationWhenInUseUsageDescription' .
# --- sheets / presentation ---
# sheet, full-screen cover, and detents usage
rg -n '\.sheet|fullScreenCover|presentationDetents' . | head
# --- alerts ---
# UIKit alerts presented from SwiftUI (sheet-stacking bug on iOS 17+)
rg -n 'UIAlertController|keyWindow' . | head
# --- truncation at large sizes ---
# labels that may truncate under accessibility Dynamic Type sizes
rg -n 'lineLimit\(|truncationMode|fixedSize' . | head
Common issues & anti-patterns
- Ignoring safe area globally:
.ignoresSafeArea()on a scroll view hides content under the Dynamic Island on iPhone 14 Pro and later. - Hardcoded font sizes:
Font.system(size: 14)does not scale with Dynamic Type — use.body,.caption,.footnote, orrelativeTo:. - Custom back button without a title: stripping the back-button label breaks conventions and confuses VoiceOver users.
- UIKit alert from SwiftUI: presenting a
UIAlertControllerviaUIApplication.shared.keyWindowbreaks sheet stacking on iOS 17 and later. Use the.alertmodifier. - Missing
.symbolVariant:Image(systemName: "heart")in a tab bar without.fillviolates tab-bar conventions. - Non-semantic colors in widgets: WidgetKit ignores dynamic colors unless
Color(.widgetBackground)and.widgetAccentable()are used. - Blocking the main thread during scroll: synchronous image loading in
cellForRowAtcauses scroll jank — load asynchronously. - Decorative haptics: firing impact feedback on every minor animation, which feels noisy and trains users to ignore it.
- Sheet for navigation: using a modal
.sheetto push a detail screen that should be aNavigationStackdestination, so the back gesture and title behavior feel wrong. - Fixed-size icon button: a 20pt icon in a 24pt frame used as a tappable button, well under the 44pt minimum and hard to hit reliably.
- No confirmation on destructive sheet: a delete action inside a sheet that fires immediately on tap with no confirmation, risking accidental data loss.
- Light-only asset: an image asset with no dark-mode variant in the catalog, so a logo or illustration glows on a dark background.
- Hardcoded accent color: a brand color set as a literal
Color(red:...)instead of an asset-catalog color set, so it ignores both dark mode and high-contrast accessibility settings. - VoiceOver order scrambled: a custom layout where the visual order and the accessibility traversal order diverge, so VoiceOver reads controls in a confusing sequence.
Required output
Return a structured report with:
- Framework and iOS version summary.
- Findings table: Screen/Component, HIG Section, Severity, Issue, Fix.
- VoiceOver and Dynamic Type pass/fail summary.
- Top three must-fix items before App Store submission.
Safety
- Do not alter
Info.plistprivacy strings without listing every change explicitly for the user to review. - Do not trigger Xcode builds or TestFlight uploads.
- Do not read or reproduce entitlement files or provisioning-profile details.
- Redact any signing identity or team-ID values surfaced during review.
- Treat accessibility and privacy gaps as submission blockers, not cosmetic notes.
Completion criteria
Done means the framework and deployment target are identified; safe area, Dynamic Type, tap targets, SF Symbols, haptics, dark mode, navigation, and VoiceOver were each checked against HIG; every finding cites a HIG area and a concrete fix; and the top three submission blockers are called out with a VoiceOver and Dynamic Type pass/fail summary.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.