iOS Design System cho AI Agent: Từ HIG Thành Ruleset Cụ Thể
Bạn bảo AI agent: "làm giúp tôi màn hình Settings kiểu iOS." Nó trả về một thứ trông... gần giống: nút bo góc hơi sai, spacing tùy hứng, font Roboto, shadow đổ nặng như Material Design đội lốt iOS. Agent không hề kém — vấn đề là "kiểu iOS" là một instruction mơ hồ. Máy không tự generalize ra "native feel" từ một tính từ.
Cách sửa không phải viết prompt hoa mỹ hơn, mà là đưa cho agent một ruleset đo được: tokens, scales, và ràng buộc cụ thể trích từ Apple Human Interface Guidelines (HIG). Bài này distill HIG thành bộ rule bạn có thể dán thẳng vào system prompt hoặc design context của agent.
Vì sao "trông giống iOS" luôn fail
Agent học từ một corpus nặng web và Material Design. Trong "đầu" nó, "iOS style" không phải một tập pixel cụ thể — nó là một vùng mờ. Những tính từ như clean, modern, native không map ra con số, nên agent buộc phải đoán, và mặc định nó đoán theo web.
Nguyên tắc cốt lõi: nếu một yêu cầu design không đo được, agent sẽ đoán. Vậy nên đừng mô tả cảm giác — hãy đưa số: 44pt touch target, 17pt body, lưới 8pt, semantic color.
- Clarity → ưu tiên legibility: Dynamic Type, contrast ≥ 4.5:1, không nhồi chữ.
- Deference → content nổi, chrome chìm: bỏ shadow nặng, viền mảnh, nền semantic.
- Depth → phân lớp bằng layering + motion, không bằng skeuomorphism.
flowchart TD
A["Prompt: 'làm UI kiểu iOS'"] --> B{Agent có ruleset?}
B -->|Không| C[Generalize từ web / Material]
C --> D[UI non-native: sai spacing, shadow nặng, hardcode màu]
B -->|Có| E[Áp tokens: 8pt grid, SF type, semantic color, SF Symbols]
E --> F[Áp component rules: nav bar, list, button]
F --> G[UI native iOS]
Spacing & layout: hệ 8pt
Mọi khoảng cách là bội số của 8 (dùng 4 cho fine-tune). Lề content hai bên màn hình: 16pt. Touch target tối thiểu 44×44pt — luật bất di bất dịch. Luôn tôn trọng safe area (notch, home indicator); đừng hardcode top = 20.
| Token | Giá trị | Dùng cho |
|---|---|---|
| Grid base | 8pt | mọi gap/padding là bội số |
| Screen margin | 16pt | lề trái/phải của content |
| Touch target min | 44×44pt | mọi phần tử tappable |
| Corner radius (button) | 12pt, continuous | nút, card nhỏ |
| Corner radius (card/sheet) | 16–20pt, continuous | card lớn, bottom sheet |
| Separator inset | 16pt | divider trong list |
RoundedRectangle(cornerRadius: 12, style: .continuous) thay cho .cornerRadius(12) cũ — khác biệt nhỏ này là một trong những "tell" rõ nhất giữa UI native và UI web.Typography: SF Pro + Dynamic Type
Đừng hardcode các size rời rạc. Map vào text styles của hệ thống — chúng tự scale theo cài đặt Dynamic Type của user.
| Text style | Size mặc định | Weight | Dùng cho |
|---|---|---|---|
| Large Title | 34pt | Regular/Bold | tiêu đề màn hình (collapse khi scroll) |
| Title 1 / 2 / 3 | 28 / 22 / 20pt | Regular | heading theo cấp |
| Headline | 17pt | Semibold | dòng nhấn trong body |
| Body | 17pt | Regular | nội dung chính |
| Subheadline | 15pt | Regular | metadata |
| Footnote | 13pt | Regular | chú thích |
| Caption | 12 / 11pt | Regular | nhãn nhỏ nhất |
Rule cho agent: body = 17pt, không bao giờ < 11pt, và luôn map font sang một text style để Dynamic Type hoạt động.
Color: semantic, không hardcode hex
iOS có hệ màu semantic tự đổi theo light/dark mode. Agent phải dùng token, không dán giá trị hex.
| Semantic token | Dùng cho |
|---|---|
label | text chính |
secondaryLabel | text phụ |
tertiaryLabel | placeholder, trạng thái disabled |
systemBackground | nền cấp 1 |
secondarySystemBackground | nền cấp 2 (grouped content) |
separator | đường kẻ phân cách |
| tint / accent | màu nhấn cho phần tử tương tác |
#FFFFFF cho nền là sai lầm phổ biến nhất: bật dark mode lên là nền trắng chói lóa. Luôn dùng systemBackground. Tương tự, đừng hardcode #000000 cho text — dùng label, để hệ thống tự xử lý cả hai chế độ.SF Symbols, không phải icon set khác
iOS dùng SF Symbols — bộ icon vector khớp metric với SF Pro. Agent đừng import Material Icons hay Font Awesome. Chọn symbol bằng tên (chevron.right, gear, trash), set weight khớp với text kế bên, và dùng đúng rendering mode (monochrome / hierarchical / palette). Icon lệch weight so với chữ là dấu hiệu lộ liễu của UI không phải native.
Components: do / don't
Nói "dùng list kiểu iOS" vẫn còn mơ hồ. Đây là rule cụ thể cho các component hay gặp nhất:
- Tab bar: ≤ 5 tab, icon SF Symbol + label ngắn, luôn ở bottom
- List: inset grouped, separator inset 16pt, chevron cho row điều hướng
- Button: filled (primary) / tinted / plain — KHÔNG đổ shadow
- Sheet: dùng detents (.medium / .large), có grabber ở trên
- Nav bar: large title, collapse mượt khi scroll
- Floating Action Button (FAB) — đó là Material, không phải iOS
- Card đổ shadow nặng, nhiều lớp
- Bottom nav > 5 tab hoặc nhồi text dài
- Hamburger menu thay cho tab bar
- Bo góc tròn đều thay vì continuous
Đóng gói thành ruleset cho agent
Gom tất cả thành một block bạn dán thẳng vào system prompt hoặc design context của agent. Đây là phần "payload" thật sự của bài viết:
# iOS Design Ruleset (cho AI agent)
## Spacing & layout
- Mọi gap/padding = bội số 8pt (4pt cho fine-tune)
- Screen margin = 16pt; touch target ≥ 44×44pt
- Corner radius: button 12pt, card/sheet 16–20pt, luôn style continuous
- Tôn trọng safe area; không hardcode offset cố định
## Typography (SF Pro, Dynamic Type)
- Body 17pt regular; Headline 17pt semibold; Large Title 34pt
- Luôn map size → text style; không bao giờ < 11pt
## Color (semantic, KHÔNG hardcode hex)
- Text: label / secondaryLabel / tertiaryLabel
- Nền: systemBackground / secondarySystemBackground
- Accent qua tint; phải hoạt động ở cả light & dark mode
## Icons
- Chỉ dùng SF Symbols; weight khớp text kế bên
## Components
- Tab bar ≤ 5; list inset grouped; button không shadow
- Sheet dùng detents; nav bar large-title collapse
- Cấm: FAB, hamburger menu, shadow nặng, bo góc tròn đều
Sai lầm thường gặp
- Shadow nặng kiểu Material thay vì viền mảnh + nền phân lớp.
- Hardcode hex → vỡ dark mode ngay khi user bật chế độ tối.
- Bỏ qua Dynamic Type → chữ không scale, fail accessibility.
- Touch target < 44pt → khó bấm, vi phạm HIG.
- Custom font thay SF Pro mà không có lý do → mất "native feel" tức thì.
Key Takeaways
- "Trông giống iOS" là instruction mơ hồ; agent cần tokens đo được, không phải tính từ.
- Ba con số neo mọi thứ: lưới 8pt, touch target 44pt, body 17pt.
- Color và type phải semantic (
label,systemBackground, text styles) để dark mode + Dynamic Type tự chạy. - Dùng SF Symbols; cấm FAB / hamburger / shadow nặng — đó là dấu hiệu UI "web đội lốt iOS".
- Đóng gói ruleset thành một block dán vào agent context: rule cụ thể luôn thắng prompt hoa mỹ.