Files of Ios UI components
wondelai/
components.md
Show the full text238 lines
iOS UI Components
Buttons
Page-level actions: Appear in nav bar (top) or action bar (bottom)
┌─────────────────────────────────┐
│ Cancel Save Edit │ ← Nav bar actions
├─────────────────────────────────┤
│ │
│ Page Content │
│ │
├─────────────────────────────────┤
│ Share Copy Delete │ ← Action bar
└─────────────────────────────────┘
On-page buttons: Often appear on cards or sections
- Primary buttons: Filled with theme color
- Secondary buttons: Outlined or text-only
- Destructive actions: Red text/color
Lists (Table Views)
Lists are fundamental to iOS design. Configure each row with:
Left side (optional):
- Icon or image
Center:
- Primary text (17pt regular)
- Secondary text (15pt or 12pt, lighter color)
- Tertiary text (if needed)
Right side (choose one):
- Chevron (→) — navigates to detail screen
- Text + Chevron — shows current value, tappable to change
- Checkmark (✓) — single selection from list
- Switch — toggle on/off
- Text button — action link
Input Controls
Most inputs are styled as list items:
Text Input:
┌─────────────────────────────────┐
│ Email │ ← Hint text disappears on typing
└─────────────────────────────────┘
Switch:
┌─────────────────────────────────┐
│ Notifications [====○] │
└─────────────────────────────────┘
Date/Time Picker:
┌─────────────────────────────────┐
│ Date [ Jan 15, 2025 ] │ ← Light gray button, expands inline
└─────────────────────────────────┘
Picker Screen Pattern:
- List item shows current value + chevron
- Tapping navigates to selection screen
- Selected option marked with checkmark
Pull-Down Menus
For short option lists without navigation:
Menu("Options") {
Button("Edit", action: edit)
Button("Share", action: share)
Divider()
Button("Delete", role: .destructive, action: delete)
}
Touch Targets & Spacing
Minimum Touch Target
44 × 44 points — This is non-negotiable for all interactive elements.
Button("Tap") {
// Action
}
.frame(minWidth: 44, minHeight: 44)
Standard Spacing Values
| Spacing | Usage |
|---|---|
| 8pt | Tight spacing (related elements) |
| 16pt | Standard spacing (sections) |
| 20pt | Screen edge margins |
| 24pt | Loose spacing (major sections) |
VStack(spacing: 16) {
// Standard component spacing
}
Menu Patterns
Context Menus
Long-press to reveal contextual actions:
Text("Item")
.contextMenu {
Button("Edit", action: edit)
Button("Share", action: share)
Divider()
Button("Delete", role: .destructive, action: delete)
}
Guidelines:
- Group related actions
- Use dividers between groups
- Destructive actions at bottom, marked red
- Include icons where helpful
Pull-Down Menus
Tap to reveal options without navigation:
Menu("Options") {
Button("Sort by Name", action: sortByName)
Button("Sort by Date", action: sortByDate)
Divider()
Menu("Filter") {
Button("Active", action: filterActive)
Button("Completed", action: filterCompleted)
}
}
When to use:
- 3-6 options that don't need full screen
- Actions that don't require additional input
- Sorting, filtering, view options
Action Sheets
For important decisions requiring attention:
.confirmationDialog("Choose Action", isPresented: $showingSheet) {
Button("Camera") { }
Button("Photo Library") { }
Button("Cancel", role: .cancel) { }
}
Guidelines:
- Title is optional (use for clarity)
- Limit to 5-6 actions
- Cancel is always last
- Destructive actions in red
Confirmation Dialogs
When to Confirm
| Action | Needs Confirmation? |
|---|---|
| Delete single item | Sometimes (if permanent) |
| Delete multiple items | Yes |
| Discard unsaved changes | Yes |
| Log out | Usually not |
| Send message | No |
| Purchase | Yes (final step) |
Alert Structure
.alert("Delete Item?", isPresented: $showingAlert) {
Button("Delete", role: .destructive, action: deleteItem)
Button("Cancel", role: .cancel) { }
} message: {
Text("This action cannot be undone.")
}
Guidelines:
- Title: Clear action question
- Message: Explain consequences (brief)
- Buttons: Specific verbs, not just "OK"
- Destructive button on left (less expected position)
- Cancel on right (easy to tap)
Undo vs. Confirm
Prefer undo when:
- Action is recoverable
- Speed matters
- Confirmations would be annoying
Require confirmation when:
- Action is irreversible
- Data/money loss possible
- Action affects others
// Undo pattern
.toolbar {
Button("Undo") { undoManager.undo() }
}
// Swipe to delete with undo toast
.swipeActions(edge: .trailing) {
Button("Delete", role: .destructive) {
withAnimation {
deleteWithUndo(item)
}
}
}
| 1 | # iOS UI Components |
| 2 | |
| 3 | ## Buttons |
| 4 | |
| 5 | **Page-level actions**: Appear in nav bar (top) or action bar (bottom) |
| 6 | |
| 7 | |
| 8 | ┌─────────────────────────────────┐ |
| 9 | │ Cancel Save Edit │ ← Nav bar actions |
| 10 | ├─────────────────────────────────┤ |
| 11 | │ │ |
| 12 | │ Page Content │ |
| 13 | │ │ |
| 14 | ├─────────────────────────────────┤ |
| 15 | │ Share Copy Delete │ ← Action bar |
| 16 | └─────────────────────────────────┘ |
| 17 | |
| 18 | |
| 19 | **On-page buttons**: Often appear on cards or sections |
| 20 | |
| 21 | Primary buttons: Filled with theme color |
| 22 | Secondary buttons: Outlined or text-only |
| 23 | Destructive actions: Red text/color |
| 24 | |
| 25 | ## Lists (Table Views) |
| 26 | |
| 27 | Lists are fundamental to iOS design. Configure each row with: |
| 28 | |
| 29 | **Left side** (optional): |
| 30 | Icon or image |
| 31 | |
| 32 | **Center**: |
| 33 | Primary text (17pt regular) |
| 34 | Secondary text (15pt or 12pt, lighter color) |
| 35 | Tertiary text (if needed) |
| 36 | |
| 37 | **Right side** (choose one): |
| 38 | Chevron (→) — navigates to detail screen |
| 39 | Text + Chevron — shows current value, tappable to change |
| 40 | Checkmark (✓) — single selection from list |
| 41 | Switch — toggle on/off |
| 42 | Text button — action link |
| 43 | |
| 44 | ## Input Controls |
| 45 | |
| 46 | Most inputs are styled as list items: |
| 47 | |
| 48 | **Text Input**: |
| 49 | |
| 50 | ┌─────────────────────────────────┐ |
| 51 | │ Email │ ← Hint text disappears on typing |
| 52 | └─────────────────────────────────┘ |
| 53 | |
| 54 | |
| 55 | **Switch**: |
| 56 | |
| 57 | ┌─────────────────────────────────┐ |
| 58 | │ Notifications [====○] │ |
| 59 | └─────────────────────────────────┘ |
| 60 | |
| 61 | |
| 62 | **Date/Time Picker**: |
| 63 | |
| 64 | ┌─────────────────────────────────┐ |
| 65 | │ Date [ Jan 15, 2025 ] │ ← Light gray button, expands inline |
| 66 | └─────────────────────────────────┘ |
| 67 | |
| 68 | |
| 69 | **Picker Screen Pattern**: |
| 70 | List item shows current value + chevron |
| 71 | Tapping navigates to selection screen |
| 72 | Selected option marked with checkmark |
| 73 | |
| 74 | ## Pull-Down Menus |
| 75 | |
| 76 | For short option lists without navigation: |
| 77 | |
| 78 | |
| 79 | Menu("Options") { |
| 80 | Button("Edit", action: edit) |
| 81 | Button("Share", action: share) |
| 82 | Divider() |
| 83 | Button("Delete", role: .destructive, action: delete) |
| 84 | } |
| 85 | |
| 86 | |
| 87 | ## Touch Targets & Spacing |
| 88 | |
| 89 | ### Minimum Touch Target |
| 90 | |
| 91 | **44 × 44 points** — This is non-negotiable for all interactive elements. |
| 92 | |
| 93 | |
| 94 | Button("Tap") { |
| 95 | // Action |
| 96 | } |
| 97 | .frame(minWidth: 44, minHeight: 44) |
| 98 | |
| 99 | |
| 100 | ### Standard Spacing Values |
| 101 | |
| 102 | | Spacing | Usage | |
| 103 | |---------|-------| |
| 104 | | 8pt | Tight spacing (related elements) | |
| 105 | | 16pt | Standard spacing (sections) | |
| 106 | | 20pt | Screen edge margins | |
| 107 | | 24pt | Loose spacing (major sections) | |
| 108 | |
| 109 | |
| 110 | VStack(spacing: 16) { |
| 111 | // Standard component spacing |
| 112 | } |
| 113 | |
| 114 | |
| 115 | |
| 116 | |
| 117 | ## Menu Patterns |
| 118 | |
| 119 | ### Context Menus |
| 120 | |
| 121 | Long-press to reveal contextual actions: |
| 122 | |
| 123 | |
| 124 | Text("Item") |
| 125 | .contextMenu { |
| 126 | Button("Edit", action: edit) |
| 127 | Button("Share", action: share) |
| 128 | Divider() |
| 129 | Button("Delete", role: .destructive, action: delete) |
| 130 | } |
| 131 | |
| 132 | |
| 133 | **Guidelines:** |
| 134 | Group related actions |
| 135 | Use dividers between groups |
| 136 | Destructive actions at bottom, marked red |
| 137 | Include icons where helpful |
| 138 | |
| 139 | ### Pull-Down Menus |
| 140 | |
| 141 | Tap to reveal options without navigation: |
| 142 | |
| 143 | |
| 144 | Menu("Options") { |
| 145 | Button("Sort by Name", action: sortByName) |
| 146 | Button("Sort by Date", action: sortByDate) |
| 147 | Divider() |
| 148 | Menu("Filter") { |
| 149 | Button("Active", action: filterActive) |
| 150 | Button("Completed", action: filterCompleted) |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | |
| 155 | **When to use:** |
| 156 | 3-6 options that don't need full screen |
| 157 | Actions that don't require additional input |
| 158 | Sorting, filtering, view options |
| 159 | |
| 160 | ### Action Sheets |
| 161 | |
| 162 | For important decisions requiring attention: |
| 163 | |
| 164 | |
| 165 | .confirmationDialog("Choose Action", isPresented: $showingSheet) { |
| 166 | Button("Camera") { } |
| 167 | Button("Photo Library") { } |
| 168 | Button("Cancel", role: .cancel) { } |
| 169 | } |
| 170 | |
| 171 | |
| 172 | **Guidelines:** |
| 173 | Title is optional (use for clarity) |
| 174 | Limit to 5-6 actions |
| 175 | Cancel is always last |
| 176 | Destructive actions in red |
| 177 | |
| 178 | |
| 179 | |
| 180 | ## Confirmation Dialogs |
| 181 | |
| 182 | ### When to Confirm |
| 183 | |
| 184 | | Action | Needs Confirmation? | |
| 185 | |--------|---------------------| |
| 186 | | Delete single item | Sometimes (if permanent) | |
| 187 | | Delete multiple items | Yes | |
| 188 | | Discard unsaved changes | Yes | |
| 189 | | Log out | Usually not | |
| 190 | | Send message | No | |
| 191 | | Purchase | Yes (final step) | |
| 192 | |
| 193 | ### Alert Structure |
| 194 | |
| 195 | |
| 196 | .alert("Delete Item?", isPresented: $showingAlert) { |
| 197 | Button("Delete", role: .destructive, action: deleteItem) |
| 198 | Button("Cancel", role: .cancel) { } |
| 199 | } message: { |
| 200 | Text("This action cannot be undone.") |
| 201 | } |
| 202 | |
| 203 | |
| 204 | **Guidelines:** |
| 205 | Title: Clear action question |
| 206 | Message: Explain consequences (brief) |
| 207 | Buttons: Specific verbs, not just "OK" |
| 208 | Destructive button on left (less expected position) |
| 209 | Cancel on right (easy to tap) |
| 210 | |
| 211 | ### Undo vs. Confirm |
| 212 | |
| 213 | **Prefer undo when:** |
| 214 | Action is recoverable |
| 215 | Speed matters |
| 216 | Confirmations would be annoying |
| 217 | |
| 218 | **Require confirmation when:** |
| 219 | Action is irreversible |
| 220 | Data/money loss possible |
| 221 | Action affects others |
| 222 | |
| 223 | |
| 224 | // Undo pattern |
| 225 | .toolbar { |
| 226 | Button("Undo") { undoManager.undo() } |
| 227 | } |
| 228 | |
| 229 | // Swipe to delete with undo toast |
| 230 | .swipeActions(edge: .trailing) { |
| 231 | Button("Delete", role: .destructive) { |
| 232 | withAnimation { |
| 233 | deleteWithUndo(item) |
| 234 | } |
| 235 | } |
| 236 | } |
| 237 | |
| 238 |
Discussion
Browse more free Claude skills.