apple-hig-designer
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseApple HIG Designer
Apple HIG 设计指南
Design beautiful, native iOS apps following Apple's Human Interface Guidelines (HIG). Create accessible, intuitive interfaces with native components, proper typography, semantic colors, and Apple's design principles.
遵循苹果人机界面指南(HIG)设计美观、原生的iOS应用。使用原生组件、合适的排版、语义化颜色和苹果设计原则,创建无障碍、直观的界面。
What This Skill Does
此技能的功能
Helps you design and build iOS apps that feel native and follow Apple's guidelines:
- Generate iOS Components - Create SwiftUI and UIKit components
- Validate Designs - Check compliance with Apple HIG
- Ensure Accessibility - VoiceOver, Dynamic Type, color contrast
- Apply Design Principles - Clarity, Deference, Depth
- Use Semantic Colors - Automatic dark mode support
- Implement Typography - San Francisco font system
- Follow Spacing - 8pt grid system and safe areas
帮助你设计和构建符合苹果指南的原生iOS应用:
- 生成iOS组件 - 创建SwiftUI和UIKit组件
- 验证设计合规性 - 检查是否符合Apple HIG
- 确保无障碍性 - VoiceOver、Dynamic Type、颜色对比度
- 应用设计原则 - 清晰、顺从、深度
- 使用语义化颜色 - 自动支持深色模式
- 实现排版规范 - San Francisco字体系统
- 遵循间距规则 - 8pt网格系统和安全区域
Apple's Design Principles
苹果的设计原则
1. Clarity
1. 清晰(Clarity)
Make content clear and focused.
Text is legible at every size, icons are precise and lucid, adornments are subtle and appropriate, and a focus on functionality drives the design.
swift
// ✅ Clear, focused content
Text("Welcome back, Sarah")
.font(.title)
.foregroundColor(.primary)
// ❌ Unclear, cluttered
Text("Welcome back, Sarah!!!")
.font(.title)
.foregroundColor(.red)
.background(.yellow)
.overlay(Image(systemName: "star.fill"))让内容清晰且聚焦。
文本在任何尺寸下都清晰易读,图标精准易懂,装饰元素简洁恰当,设计以功能为核心。
swift
// ✅ 清晰、聚焦的内容
Text("Welcome back, Sarah")
.font(.title)
.foregroundColor(.primary)
// ❌ 模糊、杂乱的内容
Text("Welcome back, Sarah!!!")
.font(.title)
.foregroundColor(.red)
.background(.yellow)
.overlay(Image(systemName: "star.fill"))2. Deference
2. 顺从(Deference)
UI helps people understand and interact with content, but never competes with it.
The interface defers to content, using a light visual treatment that keeps focus on the content and gives the content room to breathe.
swift
// ✅ Content-focused
VStack(alignment: .leading, spacing: 8) {
Text("Article Title")
.font(.headline)
Text("Article content goes here...")
.font(.body)
.foregroundColor(.secondary)
}
.padding()
// ❌ Distracting UI
VStack(spacing: 8) {
Text("Article Title")
.font(.headline)
.foregroundColor(.white)
.background(.blue)
.border(.red, width: 3)
}界面帮助用户理解和交互内容,但绝不与内容竞争注意力。
界面顺从于内容,采用轻量化视觉处理,让焦点始终在内容上,为内容留出呼吸空间。
swift
// ✅ 以内容为核心
VStack(alignment: .leading, spacing: 8) {
Text("Article Title")
.font(.headline)
Text("Article content goes here...")
.font(.body)
.foregroundColor(.secondary)
}
.padding()
// ❌ 分散注意力的界面
VStack(spacing: 8) {
Text("Article Title")
.font(.headline)
.foregroundColor(.white)
.background(.blue)
.border(.red, width: 3)
}3. Depth
3. 深度(Depth)
Visual layers and realistic motion convey hierarchy and help people understand relationships.
Distinct visual layers and realistic motion impart vitality and facilitate understanding. Touch and discoverability heighten delight and enable access to functionality without losing context.
swift
// ✅ Clear depth hierarchy
ZStack {
Color(.systemBackground)
VStack {
// Card with elevation
CardView()
.shadow(radius: 8)
}
}
// Using blur for depth
Text("Content")
.background(.ultraThinMaterial)视觉层级和真实的动效传达结构关系,帮助用户理解元素间的关联。
清晰的视觉层级和真实的动效赋予界面活力,便于用户理解。触控和可发现性提升愉悦感,让用户无需脱离上下文即可访问功能。
swift
// ✅ 清晰的深度层级
ZStack {
Color(.systemBackground)
VStack {
// 带阴影的卡片
CardView()
.shadow(radius: 8)
}
}
// 使用模糊效果营造深度
Text("Content")
.background(.ultraThinMaterial)iOS UI Components
iOS UI组件
Navigation Patterns
导航模式
1. Navigation Bar
1. 导航栏(Navigation Bar)
Top bar for navigation and actions.
swift
NavigationStack {
List {
Text("Item 1")
Text("Item 2")
}
.navigationTitle("Title")
.navigationBarTitleDisplayMode(.large)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Add") {
// Action
}
}
}
}Guidelines:
- Use large titles for top-level views
- Use inline titles for detail views
- Keep actions relevant to current context
- Maximum 2-3 toolbar items
顶部导航和操作栏。
swift
NavigationStack {
List {
Text("Item 1")
Text("Item 2")
}
.navigationTitle("Title")
.navigationBarTitleDisplayMode(.large)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Add") {
// 操作
}
}
}
}设计指南:
- 顶级视图使用大标题
- 详情视图使用内联标题
- 操作按钮需与当前上下文相关
- 工具栏最多保留2-3个按钮
2. Tab Bar
2. 标签栏(Tab Bar)
Bottom navigation for top-level destinations.
swift
TabView {
HomeView()
.tabItem {
Label("Home", systemImage: "house")
}
SearchView()
.tabItem {
Label("Search", systemImage: "magnifyingglass")
}
ProfileView()
.tabItem {
Label("Profile", systemImage: "person")
}
}Guidelines:
- 3-5 tabs maximum
- Use SF Symbols for icons
- Labels should be concise (one word)
- Never hide or disable tabs
- Don't use tab bar with toolbar in same view
底部导航栏,用于顶级目的地切换。
swift
TabView {
HomeView()
.tabItem {
Label("Home", systemImage: "house")
}
SearchView()
.tabItem {
Label("Search", systemImage: "magnifyingglass")
}
ProfileView()
.tabItem {
Label("Profile", systemImage: "person")
}
}设计指南:
- 最多3-5个标签
- 使用SF Symbols图标
- 标签文字简洁(单个单词)
- 绝不隐藏或禁用标签
- 同一视图中不要同时使用标签栏和工具栏
3. List
3. 列表(List)
Scrollable list of items.
swift
List {
Section("Today") {
ForEach(items) { item in
NavigationLink {
DetailView(item: item)
} label: {
HStack {
Image(systemName: item.icon)
.foregroundColor(.accentColor)
Text(item.title)
}
}
}
}
}
.listStyle(.insetGrouped)List Styles:
- - Edge-to-edge rows
.plain - - Rounded, inset sections (iOS default)
.insetGrouped - - For navigation sidebars
.sidebar
可滚动的项目列表。
swift
List {
Section("Today") {
ForEach(items) { item in
NavigationLink {
DetailView(item: item)
} label: {
HStack {
Image(systemName: item.icon)
.foregroundColor(.accentColor)
Text(item.title)
}
}
}
}
}
.listStyle(.insetGrouped)列表样式:
- - 边缘对齐的行
.plain - - 圆角内嵌分组(iOS默认样式)
.insetGrouped - - 用于导航侧边栏
.sidebar
4. Sheet (Modal)
4. 模态弹窗(Sheet)
Present content modally.
swift
struct ContentView: View {
@State private var showSheet = false
var body: some View {
Button("Show Details") {
showSheet = true
}
.sheet(isPresented: $showSheet) {
DetailView()
.presentationDetents([.medium, .large])
}
}
}Sheet Detents:
- - Half screen
.medium - - Full screen
.large - Custom heights available
以模态方式展示内容。
swift
struct ContentView: View {
@State private var showSheet = false
var body: some View {
Button("Show Details") {
showSheet = true
}
.sheet(isPresented: $showSheet) {
DetailView()
.presentationDetents([.medium, .large])
}
}
}弹窗尺寸:
- - 半屏
.medium - - 全屏
.large - 支持自定义高度
Form Controls
表单控件
1. Button
1. 按钮(Button)
Primary action control.
swift
// Filled button (primary action)
Button("Continue") {
// Action
}
.buttonStyle(.borderedProminent)
// Bordered button (secondary action)
Button("Cancel") {
// Action
}
.buttonStyle(.bordered)
// Plain button (tertiary action)
Button("Learn More") {
// Action
}
.buttonStyle(.plain)Button Hierarchy:
- Prominent - Primary action (one per screen)
- Bordered - Secondary actions
- Plain - Tertiary actions, links
Guidelines:
- Minimum tap target: 44x44 points
- Use verbs for button labels
- Make destructive actions require confirmation
主要操作控件。
swift
// 填充按钮(主要操作)
Button("Continue") {
// 操作
}
.buttonStyle(.borderedProminent)
// 边框按钮(次要操作)
Button("Cancel") {
// 操作
}
.buttonStyle(.bordered)
// 纯文本按钮( tertiary操作)
Button("Learn More") {
// 操作
}
.buttonStyle(.plain)按钮层级:
- Prominent - 主要操作(每个屏幕最多一个)
- Bordered - 次要操作
- Plain - tertiary操作、链接
设计指南:
- 最小点击区域:44x44点
- 按钮标签使用动词
- 破坏性操作需确认
2. TextField
2. 文本输入框(TextField)
Text input control.
swift
@State private var username = ""
@State private var password = ""
VStack(alignment: .leading, spacing: 16) {
// Standard text field
TextField("Username", text: $username)
.textFieldStyle(.roundedBorder)
.textContentType(.username)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
// Secure field
SecureField("Password", text: $password)
.textFieldStyle(.roundedBorder)
.textContentType(.password)
}Text Content Types:
- - Username field
.username - - Password field
.password - - Email field
.emailAddress - - Phone number
.telephoneNumber - - Credit card
.creditCardNumber
文本输入控件。
swift
@State private var username = ""
@State private var password = ""
VStack(alignment: .leading, spacing: 16) {
// 标准文本输入框
TextField("Username", text: $username)
.textFieldStyle(.roundedBorder)
.textContentType(.username)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
// 密码输入框
SecureField("Password", text: $password)
.textFieldStyle(.roundedBorder)
.textContentType(.password)
}文本内容类型:
- - 用户名输入框
.username - - 密码输入框
.password - - 邮箱输入框
.emailAddress - - 电话号码输入框
.telephoneNumber - - 信用卡输入框
.creditCardNumber
3. Toggle
3. 开关控件(Toggle)
Boolean control (switch).
swift
@State private var isEnabled = false
Toggle("Enable notifications", isOn: $isEnabled)
.toggleStyle(.switch)Guidelines:
- Label describes what the toggle controls
- Effect should be immediate
- Use for binary choices only
布尔值控件(开关)。
swift
@State private var isEnabled = false
Toggle("Enable notifications", isOn: $isEnabled)
.toggleStyle(.switch)设计指南:
- 标签需说明开关控制的功能
- 效果需即时生效
- 仅用于二元选择
4. Picker
4. 选择器(Picker)
Selection control.
swift
@State private var selectedSize = "Medium"
let sizes = ["Small", "Medium", "Large"]
// Menu style
Picker("Size", selection: $selectedSize) {
ForEach(sizes, id: \.self) { size in
Text(size).tag(size)
}
}
.pickerStyle(.menu)
// Segmented style (for 2-5 options)
Picker("Size", selection: $selectedSize) {
ForEach(sizes, id: \.self) { size in
Text(size).tag(size)
}
}
.pickerStyle(.segmented)Picker Styles:
- - Dropdown menu (default)
.menu - - Segmented control (2-5 options)
.segmented - - Scrollable wheel
.wheel - - Inline list (in forms)
.inline
选择控件。
swift
@State private var selectedSize = "Medium"
let sizes = ["Small", "Medium", "Large"]
// 菜单样式
Picker("Size", selection: $selectedSize) {
ForEach(sizes, id: \.self) { size in
Text(size).tag(size)
}
}
.pickerStyle(.menu)
// 分段样式(适用于2-5个选项)
Picker("Size", selection: $selectedSize) {
ForEach(sizes, id: \.self) { size in
Text(size).tag(size)
}
}
.pickerStyle(.segmented)选择器样式:
- - 下拉菜单(默认)
.menu - - 分段控件(2-5个选项)
.segmented - - 可滚动滚轮
.wheel - - 内联列表(用于表单)
.inline
Cards and Containers
卡片和容器
Card View
卡片视图(Card View)
swift
struct CardView: View {
var body: some View {
VStack(alignment: .leading, spacing: 12) {
Text("Title")
.font(.headline)
Text("Description goes here with some details about the content.")
.font(.subheadline)
.foregroundColor(.secondary)
.lineLimit(2)
Spacer()
Button("Action") {
// Action
}
.buttonStyle(.borderedProminent)
}
.padding()
.frame(width: 300, height: 200)
.background(Color(.systemBackground))
.cornerRadius(12)
.shadow(color: .black.opacity(0.1), radius: 8, x: 0, y: 4)
}
}swift
struct CardView: View {
var body: some View {
VStack(alignment: .leading, spacing: 12) {
Text("Title")
.font(.headline)
Text("Description goes here with some details about the content.")
.font(.subheadline)
.foregroundColor(.secondary)
.lineLimit(2)
Spacer()
Button("Action") {
// 操作
}
.buttonStyle(.borderedProminent)
}
.padding()
.frame(width: 300, height: 200)
.background(Color(.systemBackground))
.cornerRadius(12)
.shadow(color: .black.opacity(0.1), radius: 8, x: 0, y: 4)
}
}Typography
排版
San Francisco Font System
San Francisco 字体系统
Apple's system font designed for optimal legibility.
swift
// Dynamic Type text styles
Text("Large Title").font(.largeTitle) // 34pt
Text("Title").font(.title) // 28pt
Text("Title 2").font(.title2) // 22pt
Text("Title 3").font(.title3) // 20pt
Text("Headline").font(.headline) // 17pt semibold
Text("Body").font(.body) // 17pt regular
Text("Callout").font(.callout) // 16pt
Text("Subheadline").font(.subheadline) // 15pt
Text("Footnote").font(.footnote) // 13pt
Text("Caption").font(.caption) // 12pt
Text("Caption 2").font(.caption2) // 11pt苹果为最佳可读性设计的系统字体。
swift
// Dynamic Type 文本样式
Text("Large Title").font(.largeTitle) // 34pt
Text("Title").font(.title) // 28pt
Text("Title 2").font(.title2) // 22pt
Text("Title 3").font(.title3) // 20pt
Text("Headline").font(.headline) // 17pt semibold
Text("Body").font(.body) // 17pt regular
Text("Callout").font(.callout) // 16pt
Text("Subheadline").font(.subheadline) // 15pt
Text("Footnote").font(.footnote) // 13pt
Text("Caption").font(.caption) // 12pt
Text("Caption 2").font(.caption2) // 11ptCustom Fonts with Dynamic Type
支持Dynamic Type的自定义字体
swift
// Custom font that scales with Dynamic Type
Text("Custom Text")
.font(.custom("YourFont-Regular", size: 17, relativeTo: .body))swift
// 随Dynamic Type缩放的自定义字体
Text("Custom Text")
.font(.custom("YourFont-Regular", size: 17, relativeTo: .body))Font Weights
字体粗细
swift
Text("Light").fontWeight(.light)
Text("Regular").fontWeight(.regular)
Text("Medium").fontWeight(.medium)
Text("Semibold").fontWeight(.semibold)
Text("Bold").fontWeight(.bold)
Text("Heavy").fontWeight(.heavy)swift
Text("Light").fontWeight(.light)
Text("Regular").fontWeight(.regular)
Text("Medium").fontWeight(.medium)
Text("Semibold").fontWeight(.semibold)
Text("Bold").fontWeight(.bold)
Text("Heavy").fontWeight(.heavy)Typography Guidelines
排版指南
Do:
- ✅ Use system font (San Francisco) for consistency
- ✅ Support Dynamic Type for accessibility
- ✅ Use semantic text styles (.headline, .body, etc.)
- ✅ Minimum body text: 17pt
- ✅ Line spacing: 120-145% of font size
Don't:
- ❌ Use too many font sizes (stick to system styles)
- ❌ Make text smaller than 11pt
- ❌ Use all caps for long text
- ❌ Disable Dynamic Type
建议:
- ✅ 使用系统字体(San Francisco)以保证一致性
- ✅ 支持Dynamic Type以提升无障碍性
- ✅ 使用语义化文本样式(.headline、.body等)
- ✅ 正文最小字号:17pt
- ✅ 行间距:字号的120-145%
避免:
- ❌ 使用过多字体尺寸(遵循系统样式)
- ❌ 文本小于11pt
- ❌ 长文本使用全大写
- ❌ 禁用Dynamic Type
Colors
颜色
Semantic Colors
语义化颜色
Colors that automatically adapt to light/dark mode.
swift
// UI Element Colors
Color(.label) // Primary text
Color(.secondaryLabel) // Secondary text
Color(.tertiaryLabel) // Tertiary text
Color(.quaternaryLabel) // Watermark text
Color(.systemBackground) // Primary background
Color(.secondarySystemBackground) // Secondary background
Color(.tertiarySystemBackground) // Tertiary background
Color(.systemFill) // Fill colors
Color(.secondarySystemFill)
Color(.tertiarySystemFill)
Color(.quaternarySystemFill)
Color(.separator) // Separator lines
Color(.opaqueSeparator) // Non-transparent separator自动适配亮色/深色模式的颜色。
swift
// UI元素颜色
Color(.label) // 主文本色
Color(.secondaryLabel) // 次要文本色
Color(.tertiaryLabel) // 三级文本色
Color(.quaternaryLabel) // 水印文本色
Color(.systemBackground) // 主背景色
Color(.secondarySystemBackground) // 次要背景色
Color(.tertiarySystemBackground) // 三级背景色
Color(.systemFill) // 填充色
Color(.secondarySystemFill)
Color(.tertiarySystemFill)
Color(.quaternarySystemFill)
Color(.separator) // 分隔线
Color(.opaqueSeparator) // 不透明分隔线System Colors
系统颜色
swift
// Standard system colors (adapt to dark mode)
Color(.systemRed)
Color(.systemOrange)
Color(.systemYellow)
Color(.systemGreen)
Color(.systemMint)
Color(.systemTeal)
Color(.systemCyan)
Color(.systemBlue)
Color(.systemIndigo)
Color(.systemPurple)
Color(.systemPink)
Color(.systemBrown)
Color(.systemGray)swift
// 标准系统颜色(自动适配深色模式)
Color(.systemRed)
Color(.systemOrange)
Color(.systemYellow)
Color(.systemGreen)
Color(.systemMint)
Color(.systemTeal)
Color(.systemCyan)
Color(.systemBlue)
Color(.systemIndigo)
Color(.systemPurple)
Color(.systemPink)
Color(.systemBrown)
Color(.systemGray)Custom Colors with Dark Mode
支持深色模式的自定义颜色
swift
// Define adaptive color
extension Color {
static let customBackground = Color("CustomBackground")
}
// In Assets.xcassets, create color set with:
// - Any Appearance: #FFFFFF
// - Dark Appearance: #000000swift
// 定义自适应颜色
extension Color {
static let customBackground = Color("CustomBackground")
}
// 在Assets.xcassets中创建颜色集:
// - 通用外观:#FFFFFF
// - 深色外观:#000000Color Contrast Guidelines
颜色对比度指南
WCAG AA Compliance:
- Normal text: 4.5:1 contrast ratio minimum
- Large text (24pt+): 3:1 contrast ratio minimum
- UI components: 3:1 contrast ratio
Custom colors:
- Test with Increase Contrast enabled
- Aim for 7:1 for critical text
- Provide sufficient contrast in both modes
WCAG AA合规要求:
- 普通文本:最小对比度4.5:1
- 大文本(24pt+):最小对比度3:1
- UI组件:最小对比度3:1
自定义颜色:
- 开启增强对比度模式测试
- 关键文本目标对比度7:1
- 确保两种模式下都有足够对比度
Spacing and Layout
间距与布局
8-Point Grid System
8点网格系统
All spacing should be multiples of 8.
swift
// Spacing values
.padding(8) // 8pt
.padding(16) // 16pt (standard)
.padding(24) // 24pt
.padding(32) // 32pt
.padding(40) // 40pt
.padding(48) // 48pt
// Edge-specific padding
.padding(.horizontal, 16)
.padding(.vertical, 24)
.padding(.top, 16)
.padding(.bottom, 16)所有间距应为8的倍数。
swift
// 间距值
.padding(8) // 8pt
.padding(16) // 16pt(标准)
.padding(24) // 24pt
.padding(32) // 32pt
.padding(40) // 40pt
.padding(48) // 48pt
// 边缘特定间距
.padding(.horizontal, 16)
.padding(.vertical, 24)
.padding(.top, 16)
.padding(.bottom, 16)Safe Areas
安全区域
Respect device safe areas.
swift
// Content within safe area (default)
VStack {
Text("Content")
}
// Extend beyond safe area
VStack {
Color.blue
}
.ignoresSafeArea()
// Extend top only
VStack {
Color.blue
}
.ignoresSafeArea(edges: .top)尊重设备安全区域。
swift
// 内容在安全区域内(默认)
VStack {
Text("Content")
}
// 超出安全区域
VStack {
Color.blue
}
.ignoresSafeArea()
// 仅顶部超出安全区域
VStack {
Color.blue
}
.ignoresSafeArea(edges: .top)Touch Targets
点击区域
Minimum interactive size: 44x44 points.
swift
Button("Tap") {
// Action
}
.frame(minWidth: 44, minHeight: 44)最小交互尺寸:44x44点。
swift
Button("Tap") {
// 操作
}
.frame(minWidth: 44, minHeight: 44)Spacing Guidelines
间距指南
swift
// Component spacing
VStack(spacing: 8) { // Tight spacing
Text("Line 1")
Text("Line 2")
}
VStack(spacing: 16) { // Standard spacing
Text("Section 1")
Text("Section 2")
}
VStack(spacing: 24) { // Loose spacing
SectionView()
SectionView()
}swift
// 组件间距
VStack(spacing: 8) { // 紧凑间距
Text("Line 1")
Text("Line 2")
}
VStack(spacing: 16) { // 标准间距
Text("Section 1")
Text("Section 2")
}
VStack(spacing: 24) { // 宽松间距
SectionView()
SectionView()
}Accessibility
无障碍性
VoiceOver Support
VoiceOver 支持
Screen reader for blind and low-vision users.
swift
// Accessible label
Image(systemName: "heart.fill")
.accessibilityLabel("Favorite")
// Accessible value
Slider(value: $volume)
.accessibilityLabel("Volume")
.accessibilityValue("\(Int(volume * 100))%")
// Accessible hint
Button("Share") {
share()
}
.accessibilityHint("Shares this item with others")
// Group elements
HStack {
Image(systemName: "person")
Text("John Doe")
}
.accessibilityElement(children: .combine)
// Hidden from VoiceOver
Image("decorative")
.accessibilityHidden(true)为盲人和低视力用户设计的屏幕阅读器。
swift
// 无障碍标签
Image(systemName: "heart.fill")
.accessibilityLabel("Favorite")
// 无障碍值
Slider(value: $volume)
.accessibilityLabel("Volume")
.accessibilityValue("\(Int(volume * 100))%")
// 无障碍提示
Button("Share") {
share()
}
.accessibilityHint("Shares this item with others")
// 组合元素
HStack {
Image(systemName: "person")
Text("John Doe")
}
.accessibilityElement(children: .combine)
// 对VoiceOver隐藏
Image("decorative")
.accessibilityHidden(true)Dynamic Type
Dynamic Type 支持
Support user's preferred text size.
swift
// Automatically supported with system fonts
Text("This text scales")
.font(.body)
// Limit scaling (if necessary)
Text("This text has limits")
.font(.body)
.dynamicTypeSize(...DynamicTypeSize.xxxLarge)
// Custom font with Dynamic Type
Text("Custom font")
.font(.custom("YourFont", size: 17, relativeTo: .body))支持用户偏好的文本尺寸。
swift
// 系统字体自动支持
Text("This text scales")
.font(.body)
// 限制缩放(必要时)
Text("This text has limits")
.font(.body)
.dynamicTypeSize(...DynamicTypeSize.xxxLarge)
// 支持Dynamic Type的自定义字体
Text("Custom font")
.font(.custom("YourFont", size: 17, relativeTo: .body))Color Blindness
色盲友好设计
Design for color-blind users.
swift
// Don't rely on color alone
HStack {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.green)
Text("Success")
}
// Not just color
Circle()
.fill(.green)
// ❌ Color only
// Better with shape/icon
HStack {
Image(systemName: "checkmark.circle.fill")
Circle().fill(.green)
}
// ✅ Color + shape为色盲用户设计。
swift
// 不要仅依赖颜色
HStack {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.green)
Text("Success")
}
// 仅用颜色 ❌
Circle()
.fill(.green)
// 颜色+形状/图标 ✅
HStack {
Image(systemName: "checkmark.circle.fill")
Circle().fill(.green)
}Reduce Motion
减少动效
Respect user's motion preferences.
swift
@Environment(\.accessibilityReduceMotion) var reduceMotion
var animation: Animation {
reduceMotion ? .none : .spring()
}
Button("Animate") {
withAnimation(animation) {
// Animate
}
}尊重用户的动效偏好。
swift
@Environment(\.accessibilityReduceMotion) var reduceMotion
var animation: Animation {
reduceMotion ? .none : .spring()
}
Button("Animate") {
withAnimation(animation) {
// 动画
}
}Increase Contrast
增强对比度
Support high contrast mode.
swift
@Environment(\.colorSchemeContrast) var contrast
var textColor: Color {
contrast == .increased ? .primary : .secondary
}
Text("Content")
.foregroundColor(textColor)支持高对比度模式。
swift
@Environment(\.colorSchemeContrast) var contrast
var textColor: Color {
contrast == .increased ? .primary : .secondary
}
Text("Content")
.foregroundColor(textColor)Dark Mode
深色模式
Support both light and dark appearances.
支持亮色和深色外观。
Automatic Support
自动支持
swift
// Use semantic colors (automatic)
Color(.label) // Adapts automatically
Color(.systemBackground) // Adapts automaticallyswift
// 使用语义化颜色(自动适配)
Color(.label) // 自动适配
Color(.systemBackground) // 自动适配Testing Dark Mode
测试深色模式
swift
// Preview both modes
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.preferredColorScheme(.light)
ContentView()
.preferredColorScheme(.dark)
}
}swift
// 预览两种模式
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.preferredColorScheme(.light)
ContentView()
.preferredColorScheme(.dark)
}
}Dark Mode Guidelines
深色模式指南
Do:
- ✅ Use semantic colors
- ✅ Test with Increase Contrast
- ✅ Test with Reduce Transparency
- ✅ Ensure sufficient contrast in both modes
Don't:
- ❌ Use pure black (#000000) - use systemBackground
- ❌ Invert colors automatically
- ❌ Assume user preference
建议:
- ✅ 使用语义化颜色
- ✅ 开启增强对比度测试
- ✅ 开启减少透明度测试
- ✅ 确保两种模式下都有足够对比度
避免:
- ❌ 使用纯黑色(#000000)- 使用systemBackground
- ❌ 自动反转颜色
- ❌ 假设用户偏好
SF Symbols
SF Symbols
Apple's icon system (3000+ symbols).
swift
// Basic symbol
Image(systemName: "heart")
// Colored symbol
Image(systemName: "heart.fill")
.foregroundColor(.red)
// Sized symbol
Image(systemName: "heart")
.imageScale(.large)
// Font-based sizing
Image(systemName: "heart")
.font(.title)
// Multicolor symbols
Image(systemName: "person.crop.circle.fill.badge.checkmark")
.symbolRenderingMode(.multicolor)
// Hierarchical rendering
Image(systemName: "heart.fill")
.symbolRenderingMode(.hierarchical)
.foregroundColor(.red)苹果的图标系统(3000+图标)。
swift
// 基础图标
Image(systemName: "heart")
// 带颜色的图标
Image(systemName: "heart.fill")
.foregroundColor(.red)
// 调整大小的图标
Image(systemName: "heart")
.imageScale(.large)
// 基于字体的尺寸
Image(systemName: "heart")
.font(.title)
// 多色图标
Image(systemName: "person.crop.circle.fill.badge.checkmark")
.symbolRenderingMode(.multicolor)
// 层级渲染
Image(systemName: "heart.fill")
.symbolRenderingMode(.hierarchical)
.foregroundColor(.red)SF Symbols Guidelines
SF Symbols 指南
- Use system symbols when available
- Maintain visual weight consistency
- Use multicolor for semantic meaning
- Size appropriately for context
- 优先使用系统图标
- 保持视觉权重一致
- 多色图标用于语义化表达
- 根据上下文调整尺寸
App Icons
应用图标
Icon Sizes
图标尺寸
iOS:
- 1024x1024 (App Store)
- 180x180 (iPhone @3x)
- 120x120 (iPhone @2x)
- 167x167 (iPad Pro)
- 152x152 (iPad @2x)
watchOS:
- 1024x1024 (App Store)
- 196x196 (49mm)
- 216x216 (45mm)iOS:
- 1024x1024 (App Store)
- 180x180 (iPhone @3x)
- 120x120 (iPhone @2x)
- 167x167 (iPad Pro)
- 152x152 (iPad @2x)
watchOS:
- 1024x1024 (App Store)
- 196x196 (49mm)
- 216x216 (45mm)Icon Design Guidelines
图标设计指南
Do:
- ✅ Use simple, recognizable shapes
- ✅ Fill entire icon space
- ✅ Test on device (not just mockups)
- ✅ Use consistent visual style
Don't:
- ❌ Include text (very small)
- ❌ Use photos
- ❌ Replicate Apple hardware
- ❌ Use translucency
建议:
- ✅ 使用简单、可识别的形状
- ✅ 填满整个图标空间
- ✅ 在设备上测试(不只是原型)
- ✅ 保持视觉风格一致
避免:
- ❌ 包含文字(尺寸太小)
- ❌ 使用照片
- ❌ 模仿苹果硬件
- ❌ 使用半透明效果
Animation and Motion
动画与动效
Standard Animations
标准动画
swift
// Spring animation (natural, bouncy)
withAnimation(.spring()) {
offset = 100
}
// Linear animation
withAnimation(.linear(duration: 0.3)) {
opacity = 0
}
// Ease in/out
withAnimation(.easeInOut(duration: 0.3)) {
scale = 1.2
}swift
// 弹簧动画(自然、有弹性)
withAnimation(.spring()) {
offset = 100
}
// 线性动画
withAnimation(.linear(duration: 0.3)) {
opacity = 0
}
// 缓入缓出动画
withAnimation(.easeInOut(duration: 0.3)) {
scale = 1.2
}Gesture-Driven
手势驱动动画
swift
@State private var offset = CGSize.zero
var body: some View {
Circle()
.offset(offset)
.gesture(
DragGesture()
.onChanged { value in
offset = value.translation
}
.onEnded { _ in
withAnimation(.spring()) {
offset = .zero
}
}
)
}swift
@State private var offset = CGSize.zero
var body: some View {
Circle()
.offset(offset)
.gesture(
DragGesture()
.onChanged { value in
offset = value.translation
}
.onEnded { _ in
withAnimation(.spring()) {
offset = .zero
}
}
)
}Motion Guidelines
动效指南
- Keep animations under 0.3 seconds
- Use spring animations for interactive elements
- Respect Reduce Motion setting
- Provide visual feedback for all interactions
- 动画时长控制在0.3秒内
- 交互元素使用弹簧动画
- 尊重减少动效设置
- 所有交互都提供视觉反馈
Best Practices
最佳实践
Navigation
导航
- Hierarchical - Use NavigationStack for drilldown
- Flat - Use TabView for peer destinations
- Content-Driven - Use for media apps
- 层级式 - 使用NavigationStack进行深度导航
- 扁平式 - 使用TabView切换同级目的地
- 内容驱动式 - 适用于媒体类应用
Feedback
反馈
- Visual - Highlight on tap
- Haptic - Use UIImpactFeedbackGenerator
- Audio - Use system sounds sparingly
- 视觉反馈 - 点击时高亮
- 触觉反馈 - 使用UIImpactFeedbackGenerator
- 音频反馈 - 谨慎使用系统音效
Loading States
加载状态
swift
struct LoadingView: View {
var body: some View {
VStack {
ProgressView()
.scaleEffect(1.5)
Text("Loading...")
.font(.caption)
.foregroundColor(.secondary)
.padding(.top)
}
}
}swift
struct LoadingView: View {
var body: some View {
VStack {
ProgressView()
.scaleEffect(1.5)
Text("Loading...")
.font(.caption)
.foregroundColor(.secondary)
.padding(.top)
}
}
}Error States
错误状态
swift
struct ErrorView: View {
let message: String
let retry: () -> Void
var body: some View {
VStack(spacing: 16) {
Image(systemName: "exclamationmark.triangle")
.font(.system(size: 48))
.foregroundColor(.orange)
Text("Something went wrong")
.font(.headline)
Text(message)
.font(.subheadline)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
Button("Try Again") {
retry()
}
.buttonStyle(.borderedProminent)
}
.padding()
}
}swift
struct ErrorView: View {
let message: String
let retry: () -> Void
var body: some View {
VStack(spacing: 16) {
Image(systemName: "exclamationmark.triangle")
.font(.system(size: 48))
.foregroundColor(.orange)
Text("Something went wrong")
.font(.headline)
Text(message)
.font(.subheadline)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
Button("Try Again") {
retry()
}
.buttonStyle(.borderedProminent)
}
.padding()
}
}Empty States
空状态
swift
struct EmptyStateView: View {
var body: some View {
VStack(spacing: 16) {
Image(systemName: "tray")
.font(.system(size: 64))
.foregroundColor(.secondary)
Text("No Items")
.font(.title2)
Text("Your items will appear here")
.font(.subheadline)
.foregroundColor(.secondary)
Button("Add Item") {
// Action
}
.buttonStyle(.borderedProminent)
}
}
}swift
struct EmptyStateView: View {
var body: some View {
VStack(spacing: 16) {
Image(systemName: "tray")
.font(.system(size: 64))
.foregroundColor(.secondary)
Text("No Items")
.font(.title2)
Text("Your items will appear here")
.font(.subheadline)
.foregroundColor(.secondary)
Button("Add Item") {
// 操作
}
.buttonStyle(.borderedProminent)
}
}
}Platform Considerations
平台适配注意事项
iPhone
iPhone
- Design for various sizes (SE, Pro, Pro Max)
- Support portrait and landscape
- Use safe areas for notch/Dynamic Island
- Consider one-handed use
- 适配多种尺寸(SE、Pro、Pro Max)
- 支持竖屏和横屏
- 为刘海屏/灵动岛预留安全区域
- 考虑单手操作体验
iPad
iPad
- Support multitasking (Split View, Slide Over)
- Use sidebars for navigation
- Adapt to larger screen (don't just scale)
- Consider keyboard shortcuts
- Support external displays
- 支持多任务(分屏、侧拉)
- 使用侧边栏进行导航
- 适配大屏幕(不要只是缩放)
- 支持键盘快捷键
- 支持外接显示器
Apple Watch
Apple Watch
- Glanceable information
- Large touch targets (>44pt)
- Minimal interaction required
- Use Digital Crown for scrolling
- Support Always-On display
- 信息一目了然
- 大点击区域(>44pt)
- 最少交互操作
- 使用数码表冠滚动
- 支持常亮显示
Resources
资源
"Design is not just what it looks like and feels like. Design is how it works." - Steve Jobs