移动/游戏
设计原生 iOS 界面时如何遵循 Apple HIG…
当构建 iPhone/iPad 应用、使用 SwiftUI/UIKit、需要适配深色模式、动态字体、安全区域或让应用感觉像原生 iOS 时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
设计原生 iOS 界面时如何遵循 App通用
解决思路
- 按 6 项快速诊断逐项打分(每项 1 分),再加最多 4 分原生惯用法:语义颜色/文本样式无硬编码 +1、使用系统控件而非自定义重实现 +1、标准手势与有意义触觉反馈 +1、SF Symbols 与正确应用图标形状 +1;总分 9-10 为原生,5-6 为可用但泄露 Android 惯用法,≤3 为失败;始终说明得分与达到 10/10 所需的具体改进。
- 布局与安全区域:先为最小屏幕设计(375pt 宽,iPhone SE);安全区域保护内容不被刘海、灵动岛、Home 指示器遮挡,绝不把交互元素放在其下;标准内容边距 16-20pt,间距增量 8/16/24pt;最小触控目标与列表行高 44pt。
- 布局模式:状态栏经典 20pt、灵动岛设备 44-54pt;导航栏 44pt 标准行 + 约 52pt 大标题(共约 96pt);内容区灵活可滚动并尊重安全区域;标签栏 49pt 高、半透明带模糊;Home 指示器底部 34pt 内边距。
- 布局代码:使用默认尊重安全区域的 VStack;.ignoresSafeArea() 仅用于背景和装饰,绝不用于交互内容;在多种尺寸上测试,包括 iPhone SE 和 Pro Max。
- 排版与动态字体:使用 San Francisco(SF Pro)与语义文本样式;大标题 34pt Bold、标题 17pt Medium、正文 17pt Regular、说明 12-13pt、次要文本 15pt 60% 不透明度;最小文本 11pt(仅说明/次要);行高至少 1.3 倍字号;移动端最佳行长 35-50 字符;始终左对齐、非两端对齐。
- 排版代码:使用 .font(.title)、.font(.body)、.font(.caption) 而非硬编码尺寸;自定义间距用 @ScaledMetric;层级优先用字重和颜色变化而非极端字号差异;在最大动态字体尺寸下测试所有布局。
- 颜色与深色模式:使用 Color(.label)、Color(.secondaryLabel)、Color(.systemBackground) 而非硬编码颜色;Color(.systemBlue) 为默认色调,.systemRed 用于破坏性操作,.systemGreen 用于成功;深色模式反转文本颜色并加深背景同时保持相对层级,强调色需降低亮度、提高饱和度;两种模式均保持 4.5:1 对比度并在开发中预览。
- 颜色代码:在预览中用 .preferredColorScheme(.light) 和 .dark 并排测试;自定义颜色在 Asset Catalog 中定义明暗变体而非代码中;绝不假设背景是白或黑;开启 Increase Contrast 测试。
- 导航模式:标签栏 2-5 个主要目的地、始终可见、每个标签记住状态;导航栏返回按钮左上、标题居中或大标题、操作右上,大标题滚动时折叠;模态用于聚焦任务,通过下滑或显式关闭按钮退出;绝不使用汉堡菜单;搜索栏可位于导航栏下方、下拉才显示。
- 导航代码:返回按钮文本应为上一屏标题而非“Back”;标签标签用单词(“Home”“Search”),模态标题描述任务(“New Message”“Edit Profile”);SwiftUI 中使用 NavigationStack(而非已弃用的 NavigationView)。
- 控件与输入:页面级操作放在导航栏(顶部)或操作栏(底部);主按钮用主题色填充,次按钮描边或纯文本;破坏性操作用红色且不可逆时需确认;列表是 iOS 基础内容模式;键盘类型匹配输入(.emailAddress、.phonePad、.URL),用 .textContentType 支持自动填充。
- 控件代码:.keyboardType(.emailAddress) 搭配 .textContentType(.emailAddress);优先系统确认 .alert() 或 .confirmationDialog();列表行用 .swipeActions;主操作按钮放在屏幕底部拇指可及处。
- 无障碍:每个交互元素需要 .accessibilityLabel,状态用 .accessibilityValue,效果用 .accessibilityHint;相关元素用 .accessibilityElement(children: .combine) 分组;支持所有尺寸的动态字体并在最大设置下测试;遵守 44x44pt 触控目标和 4.5:1 对比度作为无障碍要求;绝不只用颜色传达含义。
- 无障碍代码:标签写名词(“Favorite”“Settings”),提示写动作(“Shares this item with others”);仅用 VoiceOver 测试完整应用流程;用 Xcode 的 Accessibility Inspector 审计对比度和标签。
- 图标与图像:所有标准图标使用 SF Symbols(Image(systemName:)),随文本缩放;应用图标导出 1024x1024px 方形,iOS 自动应用超椭圆(squircle)遮罩(圆角半径 = 边长 x 0.222,61% 平滑);iOS 18+ 支持浅色、深色、着色图标变体;避免图标中出现文字,保持简单可识别轮廓。
- 图标代码:使用 Image(systemName: "heart.fill"),多色深度用 .symbolRenderingMode(.hierarchical);用 .imageScale(.large) 或 .font() 让符号相对文本缩放;在 Apple 免费 SF Symbols 应用中浏览符号。
- 手势与触觉:绝不覆盖从边缘右滑(返回)、模态下滑(关闭)、列表下拉(刷新);行左滑显示操作,长按显示上下文菜单,捏合缩放图像和地图;三种触觉类型:impact(物理动作)、notification(结果)、selection(UI 变化);触觉应微妙有意义,绝不持续或烦人。
- 手势代码:物理交互用 UIImpactFeedbackGenerator(style: .medium),UI 状态变化用 UISelectionFeedbackGenerator();结果用 UINotificationFeedbackGenerator() 搭配 .success、.warning、.error;触发触觉前调用 .prepare() 以减少延迟。
- 避免常见错误:不覆盖标准手势;触控目标不小于 44pt;不忽略安全区域;不在 iOS 上用 Android 模式(汉堡菜单、顶部标签、FAB);不跳过深色模式;不硬编码字号;不用低对比度文本;不在真机上测试会遗漏性能、触觉和安全区域边缘情况。
- 发布前审计:在 iPhone SE 和 Pro Max 上检查安全区域;用 .frame(minWidth: 44, minHeight: 44) 增大点击区域;用语义系统颜色替换硬编码颜色;用语义文本样式并在最大设置测试;为所有交互元素添加标签、值、提示;用标签栏替换汉堡菜单,使用标准 push/modal 导航。
- 系统表面:请求相机、位置、联系人等受保护资源时参考隐私权限参考(请求时机、预权限引导屏、用途字符串措辞、被拒恢复路径);构建主屏小组件、App Clip、实时活动或分享/操作扩展时参考小组件扩展参考;接入 Siri/Shortcuts 意图、Handoff、拖放、通用链接和 Spotlight 索引时参考系统集成参考。
- 伦理边界:绝不把广告伪装成原生控件,也不让破坏性操作容易被误触发;绝不使用暗示不存在功能的图标或违背 iOS 惯例(垃圾桶=删除,不是归档)。
适用边界 · 注意事项
- 非 iOS 平台(Android、Web、桌面)的界面设计,应使用对应平台规范
- 仅需通用 UI 打磨或可供性设计时,应参考 refactoring-ui 或 design-everyday-things
- 无法在真机或 Xcode 预览中测试安全区域、动态字体、深色模式和 VoiceOver 的场景