Install
$ agentstack add skill-cruisediary-apple-app-review-skills-dynamic-type-support ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Skill: Dynamic Type Support
Purpose
Detects fixed font sizes, fixed-height text containers, and Dynamic Type suppression patterns that prevent text from scaling with the user's preferred reading size, violating Apple's HIG Typography guidelines.
Apple Guideline
- Primary: HIG — Typography (Apple Human Interface Guidelines)
- Related: HIG — Accessibility
- Reference:
references/hig/adaptive-layout.md
Real-World Rejection Cases
- Case: App with fixed font size 14 — text unreadable at large accessibility sizes
Source: App Store Connect rejection feedback Root cause: All labels used .font(.system(size: 14)) with a hard-coded size instead of a semantic style like .font(.body) — fixed numeric sizes do not scale with the user's accessibility setting.
- Case: Fixed-height cell rows clipping text for users with large Dynamic Type
Source: Apple Developer Forums Root cause: UITableViewCell height was hardcoded to 44 pt; at XXL accessibility size, label text overflowed the cell boundary and was clipped, causing a functional failure under HIG.
Trigger
Invoke on any iOS project that displays user-facing text to verify Dynamic Type is supported.
Inputs
| Name | Type | Default | Description | |------|------|---------|-------------| | project_root | path | cwd | iOS/macOS project root | | shared_context | object | nil | Pre-collected context from appstore-full-audit Phase 1 |
Actions
Phase 1: Context Collection
Skip this phase if shared_context is provided.
Glob**/*.swift— collect Swift source files.Glob**/*.m— collect Objective-C source files.Glob**/*.storyboardand**/*.xib— note Interface Builder files where font and row-height properties may need manual review.
Phase 2: Checks
- Fixed system font sizes (SwiftUI)
Grep pattern \.font\(\.system\(size: in **/*.swift Every match using a numeric literal → 🟡 MEDIUM. In SwiftUI, replace with semantic styles: .font(.body), .font(.headline), .font(.caption) — these scale automatically with Dynamic Type. Do not add .dynamicTypeSize to a fixed-size font; that modifier constrains the size range, it does not make a hard-coded size scale. Do not use UIFontMetrics in SwiftUI; that is a UIKit class only.
- Fixed-height text containers (SwiftUI)
Grep pattern \.frame\(height: [0-9] in **/*.swift Inspect each match for proximity to a Text( view. A fixed numeric height wrapping a Text view will clip content at large Dynamic Type sizes → 🟡 MEDIUM.
- Dynamic Type suppression
Grep pattern minimumScaleFactor in **/*.swift and **/*.m A minimumScaleFactor less than 1.0 causes text to shrink rather than reflow, suppressing Dynamic Type intent → 🟡 MEDIUM. Flag all occurrences for review.
- UIKit fixed font without UIFontMetrics
Grep pattern UIFont\.systemFont\(ofSize: in **/*.swift and **/*.m Any call not followed by a UIFontMetrics scaling call → 🟡 MEDIUM. The correct pattern is UIFontMetrics.default.scaledFont(for:).
Phase 3: Output
Collect all findings from Phase 2 and build the prioritised findings list below. Include file paths and line numbers. Omit tiers with no findings.
Output Format
## Dynamic Type Support — Findings
### 🔴 CRITICAL — Guaranteed rejection
- [ ] TODO: — `file:line` — HIG Typography
### 🟠 HIGH — Very likely rejection
- [ ] TODO: — `file:line` — HIG Typography
### 🟡 MEDIUM — Possible rejection
- [ ] TODO: — `file:line`
### 🟢 LOW — Best practice
- [ ] TODO:
Tools Used
Glob, Grep, Read
Constraints
- Read-only. No file edits.
- No network calls.
- Skip Phase 1 if
shared_contextis provided by orchestrating agent. - Works on Swift, Objective-C, React Native, Flutter projects.
Quick Commands
Run these in your project root to check manually:
# Find fixed font sizes not using UIFontMetrics
!grep -rn "\.system(size:\|systemFont(ofSize:" . --include="*.swift" | grep -v "UIFontMetrics\|scaledFont"
# Find fixed-height containers wrapping text
!grep -rn "\.frame(height:" . --include="*.swift"
Swift Anti-Pattern Reference
examples/swift/LayoutPatterns.swift
Detection Steps
- Find target files
- Glob:
**/*.swift,**/*.m
- Search for rejection patterns (two-pass approach required)
- Pass A — Grep
\.systemFont(ofSize:→ collect all matches - Pass B — Grep
UIFontMetricsin the same files; lines not covered by Pass B are fixed-size fonts - Grep
UIFont(name:→ custom font; check same file forUIFontMetrics.default.scaledFontorscaledFont(for: - Grep
heightAnchor\.constant =\|frame\.size\.height =— fixed-height containers (manual check: is the container holding a label?) - Grep
numberOfLines = 1— single-line labels (verify surrounding context foradjustsFontSizeToFitWidth)
- Determine verdict
- Fixed font size on a visible label (not icon/decoration) → 🟡 MEDIUM
- Fixed-height container clipping label text → 🟡 MEDIUM
UIFontMetricsor SwiftUI semantic fonts (.body,.headline) used → 🟢 pass
- Report
- File path + line of fixed-size font usage
- Fix: Wrap custom fonts with
UIFontMetrics(forTextStyle: .body).scaledFont(for: font); useadjustsFontForContentSizeCategory = trueon labels
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: cruisediary
- Source: cruisediary/apple-app-review-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.