提示信息
# 同伴 App — UI 设计规范 (Design Tokens)
> 所有页面统一引用 Theme 目录下的 Token,禁止硬编码颜色、字号、间距。
> 换肤只需修改 `Assets.xcassets → AccentColor`,全局自动生效。
---
## 一、文件结构
```
Theme/
├── AppColors.swift # 语义色(品牌色、背景、文字、功能色)
├── AppFonts.swift # 字体梯度(largeTitle → footnote)
├── AppSpacing.swift # 间距梯度(xs=4 → xxxl=48)+ 页面/卡片边距
├── AppSizes.swift # 控件高度、圆角、头像尺寸、边框宽度
└── AppStyles.swift # ViewModifier 组合(输入框、按钮、Chip、卡片)
```
---
## 二、颜色 (AppColors)
### 2.1 品牌色
| Token | 值 | 用途 |
|---|---|---|
| `Color.brand` | `AccentColor`(当前系统蓝) | 按钮、链接、高亮 |
| `Color.brandSoft` | `AccentColor` 15% 透明 | 选中背景、淡色高亮 |
> **换色方法**:修改 `Assets.xcassets → AccentColor` 的 Any / Dark 色值即可。
> 所有代码引用 `Color.brand`,不允许直接写 `.blue` / `.orange`。
### 2.2 背景色(自动适配深色/浅色)
| Token | Light | Dark |
|---|---|---|
| `backgroundPrimary` | 白 | 纯黑 |
| `backgroundSecondary` | 浅灰 | 深灰 |
| `backgroundTertiary` | 更浅灰 | 中灰 |
| `backgroundGrouped` | 分组列表背景 | — |
### 2.3 文字色
| Token | Light | Dark |
|---|---|---|
| `textPrimary` | 黑 | 白 |
| `textSecondary` | 灰 | 浅灰 |
| `textTertiary` | 更浅灰 | 更浅灰 |
| `textPlaceholder` | 占位符灰 | — |
### 2.4 功能色
| Token | 值 | 场景 |
|---|---|---|
| `success` | 系统绿 | 成功提示 |
| `warning` | 系统橙 | 警告提示 |
| `danger` | 系统红 | 错误、删除、退出 |
---
## 三、字体 (AppFonts)
| Token | 大小 | 字重 | 场景 |
|---|---|---|---|
| `largeTitle` | 28pt | Bold | 启动页大标题 |
| `title` | 22pt | Semibold | 页面标题 |
| `subtitle` | 17pt | Medium | 区块标题、表单标签 |
| `body` | 15pt | Regular | 正文、输入框内容 |
| `caption` | 13pt | Regular | 说明文字、时间戳 |
| `footnote` | 11pt | Regular | 极小说明、版权 |
| `button` | 16pt | Semibold | 按钮文字 |
---
## 四、间距 (AppSpacing)
| Token | 值 | 典型场景 |
|---|---|---|
| `xs` | 4pt | 文字与图标间距 |
| `sm` | 8pt | 紧凑行间距、输入框左右码间距 |
| `md` | 12pt | 列表行间距、卡片内小间距 |
| `lg` | 16pt | 表单字段间距、输入框内边距 |
| `xl` | 24pt | 区块间距 |
| `xxl` | 32pt | 大区块间距 |
| `xxxl` | 48pt | 页面头部底部留白 |
| `pageHorizontal` | 24pt | 页面左右安全边距 |
| `cardPadding` | 16pt | 卡片内边距 |
| `listRowSpacing` | 12pt | 列表行间距 |
---
## 五、尺寸 (AppSizes)
### 5.1 控件高度
| Token | 值 | 场景 |
|---|---|---|
| `inputHeight` | 52pt | 所有输入框 |
| `buttonHeight` | 54pt | 主/次级按钮 |
| `smallButtonHeight` | 36pt | 验证码按钮、小操作 |
| `chipHeight` | 40pt | 标签选择 Chip |
### 5.2 圆角
| Token | 值 | 场景 |
|---|---|---|
| `cornerRadiusSm` | 8pt | 小标签、小卡片 |
| `cornerRadiusMd` | 12pt | 输入框、标准卡片 |
| `cornerRadiusLg` | 16pt | 大卡片、Sheet |
| `capsuleRadius` | 100pt | 胶囊按钮 |
### 5.3 头像
| Token | 值 | 场景 |
|---|---|---|
| `avatarSmall` | 40pt | 列表行小头像 |
| `avatarMedium` | 48pt | 标准头像 |
| `avatarLarge` | 64pt | 个人主页头像 |
| `avatarXLarge` | 120pt | 注册页设置头像 |
### 5.4 边框
| Token | 值 | 场景 |
|---|---|---|
| `borderWidth` | 0.5pt | 默认分割线/边框 |
| `borderWidthSelected` | 2pt | 选中态描边 |
---
## 六、样式修饰器 (AppStyles)
### 6.1 输入框
```swift
TextField("手机号", text: $phone)
.glassInput() // → 统一高度 52pt + ultraThinMaterial + 圆角 12
```
### 6.2 主按钮
```swift
Button("立即登录") { ... }
.primaryButtonStyle() // → 全宽 54pt + 品牌色玻璃效果
```
### 6.3 次级按钮
```swift
Button("取消") { ... }
.secondaryButtonStyle() // → 全宽 54pt + 超薄玻璃 + 品牌色文字
```
### 6.4 玻璃背景
```swift
VStack { ... }
.glassBackground(material: .thinMaterial, cornerRadius: 16)
```
### 6.5 可选 Chip
```swift
Text("直")
.selectableChip(isSelected: value == 1)
```
### 6.6 可选卡片
```swift
VStack { ... }
.selectableCard(isSelected: gender == 1)
```
### 6.7 分段选择器(替代系统 Picker)
```swift
AppSegmentedPicker(
options: [("验证码登录", LoginMode.sms), ("密码登录", LoginMode.password)],
selection: $mode
)
```
> 系统 `Picker(.segmented)` 高度过矮且不可控。统一使用 `AppSegmentedPicker`,
> 高度为 `AppSizes.smallButtonHeight`(36pt),选中态使用品牌色。
### 6.8 键盘收起
```swift
ScrollView { ... }
.dismissKeyboardOnTap()
```
> **强制规范**:所有含输入框的页面必须添加 `.dismissKeyboardOnTap()`。
> 该修饰器提供三重收起机制:
> 1. 滚动时自动收起(`.scrollDismissesKeyboard(.interactively)`)
> 2. 键盘工具栏"完成"按钮
> 3. 点击空白区域收起
---
## 七、深色/浅色模式适配
本项目**全量使用系统语义色**,无需额外适配:
| 类别 | 做法 |
|---|---|
| 背景色 | `Color(.systemBackground)` 系列,系统自动翻转 |
| 文字色 | `Color(.label)` 系列,系统自动翻转 |
| 品牌色 | `AccentColor` 在 Asset Catalog 中可分别设置 Any / Dark |
| 玻璃效果 | `.ultraThinMaterial` 等自动适配深色模式 |
| 功能色 | `Color.green` / `.red` / `.orange` 均为系统自适应色 |
**禁止事项**:
- 不得使用 `Color.white` / `Color.black` 做背景或文字
- 不得使用 `.opacity()` 模拟浅灰 — 用 `Color.backgroundSecondary` 代替
- 不得硬编码 hex 色值 — 如需自定义色,添加到 Asset Catalog
---
## 八、后续换肤流程
1. 打开 `Assets.xcassets → AccentColor`
2. 修改 Any Appearance 和 Dark Appearance 色值
3. 全局 `Color.brand` / `Color.brandSoft` / `.tint` 自动跟随
4. 无需改动任何 Swift 代码
---
## 九、调试工具(仅 DEBUG)
DEBUG 构建下,App 右侧显示一个可拖拽的调试浮窗(蚂蚁图标)。
点击打开网络日志控制台,可查看:
- 所有 API 请求的方法、URL、状态码、耗时
- 请求头、请求体、响应体(JSON 格式化)
- 错误信息
相关文件:
```
Debug/
├── NetworkLogger.swift # 请求/响应捕获(最多 200 条)
└── DebugOverlay.swift # 浮窗 UI + 日志控制台 + 详情页
```
> 所有代码包裹在 `#if DEBUG` 中,Release 构建零开销。