8.1 Form 组件
核心概念
Form 是 SwiftUI 中用于创建表单界面的专用组件,它提供了:
- 自动的分组和分隔线
- 自适应的布局
- 与系统设置一致的外观
- 支持多种表单控件
基本使用
1import SwiftUI 2 3struct ContentView: View { 4 var body: some View { 5 NavigationStack { 6 Form { 7 Section { 8 Text("个人信息") 9 } 10 11 Section { 12 Text("姓名: 张三") 13 Text("年龄: 25") 14 Text("邮箱: zhangsan@example.com") 15 } 16 } 17 .navigationTitle("个人资料") 18 } 19 } 20} 21
动态表单
1import SwiftUI 2 3struct ContentView: View { 4 @State private var name = "张三" 5 @State private var age = 25 6 @State private var email = "zhangsan@example.com" 7 8 var body: some View { 9 NavigationStack { 10 Form { 11 Section { 12 Text("个人信息") 13 } 14 15 Section { 16 TextField("姓名", text: $name) 17 Stepper("年龄: \(age)", value: $age, in: 1...100) 18 TextField("邮箱", text: $email) 19 } 20 } 21 .navigationTitle("编辑资料") 22 } 23 } 24} 25
8.2 常见表单控件组合
基础控件
| 控件类型 | 用途 | 示例代码 |
|---|---|---|
| TextField | 文本输入 | TextField("输入", text: $text) |
| SecureField | 密码输入 | SecureField("密码", text: $password) |
| Toggle | 开关 | Toggle("启用", isOn: $isEnabled) |
| Picker | 选择器 | Picker("选择", selection: $selection) { ... } |
| Stepper | 步进器 | Stepper("数量: \(count)", value: $count) |
| Slider | 滑块 | Slider(value: $value, in: 0...100) |
| DatePicker | 日期选择 | DatePicker("日期", selection: $date) |
组合使用
1import SwiftUI 2 3struct ContentView: View { 4 @State private var notifications = true 5 @State private var sound = true 6 @State private var theme = "浅色" 7 @State private var brightness = 0.5 8 9 var body: some View { 10 NavigationStack { 11 Form { 12 Section { 13 Toggle("通知", isOn: $notifications) 14 Toggle("声音", isOn: $sound) 15 } 16 17 Section { 18 Picker("主题", selection: $theme) { 19 Text("浅色").tag("浅色") 20 Text("深色").tag("深色") 21 Text("跟随系统").tag("跟随系统") 22 } 23 } 24 25 Section { 26 Text("亮度: \(Int(brightness * 100))%") 27 Slider(value: $brightness, in: 0...1) 28 } 29 } 30 .navigationTitle("设置") 31 } 32 } 33} 34
8.3 表单验证
基本验证
1import SwiftUI 2 3struct ContentView: View { 4 @State private var email = "" 5 @State private var password = "" 6 @State private var showError = false 7 @State private var errorMessage = "" 8 9 var body: some View { 10 NavigationStack { 11 Form { 12 Section { 13 TextField("邮箱", text: $email) 14 .keyboardType(.emailAddress) 15 SecureField("密码", text: $password) 16 } 17 18 Section { 19 Button("登录") { 20 if !validateForm() { 21 showError = true 22 } 23 } 24 } 25 } 26 .navigationTitle("登录") 27 .alert("错误", isPresented: $showError) { 28 Button("确定") {} 29 } message: { 30 Text(errorMessage) 31 } 32 } 33 } 34 35 func validateForm() -> Bool { 36 if email.isEmpty { 37 errorMessage = "请输入邮箱" 38 return false 39 } 40 if !email.contains("@") { 41 errorMessage = "请输入有效的邮箱" 42 return false 43 } 44 if password.count < 6 { 45 errorMessage = "密码至少需要6个字符" 46 return false 47 } 48 return true 49 } 50} 51
实时验证
1import SwiftUI 2 3struct ContentView: View { 4 @State private var email = "" 5 @State private var password = "" 6 7 var emailIsValid: Bool { 8 !email.isEmpty && email.contains("@") 9 } 10 11 var passwordIsValid: Bool { 12 password.count >= 6 13 } 14 15 var body: some View { 16 NavigationStack { 17 Form { 18 Section { 19 TextField("邮箱", text: $email) 20 .keyboardType(.emailAddress) 21 .foregroundColor(emailIsValid ? .primary : .red) 22 23 SecureField("密码", text: $password) 24 .foregroundColor(passwordIsValid ? .primary : .red) 25 26 if !emailIsValid && !email.isEmpty { 27 Text("请输入有效的邮箱") 28 .foregroundColor(.red) 29 .font(.caption) 30 } 31 32 if !passwordIsValid && !password.isEmpty { 33 Text("密码至少需要6个字符") 34 .foregroundColor(.red) 35 .font(.caption) 36 } 37 } 38 39 Section { 40 Button("登录") { 41 // 登录逻辑 42 } 43 .disabled(!emailIsValid || !passwordIsValid) 44 } 45 } 46 .navigationTitle("登录") 47 } 48 } 49} 50
8.4 实战:用户设置页面
完整示例
1import SwiftUI 2 3struct ContentView: View { 4 @State private var notifications = true 5 @State private var sound = true 6 @State private var haptic = true 7 @State private var darkMode = false 8 @State private var language = "简体中文" 9 @State private var autoLock = 5 // 分钟 10 11 var body: some View { 12 NavigationStack { 13 List { 14 Section("通知设置") { 15 Toggle("推送通知", isOn: $notifications) 16 Toggle("声音", isOn: $sound) 17 Toggle("震动", isOn: $haptic) 18 } 19 20 Section("外观设置") { 21 Toggle("深色模式", isOn: $darkMode) 22 } 23 24 Section("语言设置") { 25 Picker("语言", selection: $language) { 26 Text("简体中文").tag("简体中文") 27 Text("English").tag("English") 28 } 29 } 30 31 Section("安全设置") { 32 Picker("自动锁定", selection: $autoLock) { 33 Text("30秒").tag(0) 34 Text("1分钟").tag(1) 35 Text("5分钟").tag(5) 36 Text("10分钟").tag(10) 37 Text("永不").tag(-1) 38 } 39 } 40 41 Section("关于") { 42 HStack { 43 Text("版本") 44 Spacer() 45 Text("1.0.0") 46 .foregroundColor(.gray) 47 } 48 49 Button("检查更新") { 50 // 检查更新逻辑 51 } 52 53 Button("隐私政策") { 54 // 打开隐私政策 55 } 56 } 57 } 58 .navigationTitle("设置") 59 } 60 } 61} 62
分组样式
1Form { 2 // 表单内容 3} 4.formStyle(.grouped) // 分组样式 5
最佳实践
- 分组逻辑:按照功能将表单控件分组
- 标签清晰:为每个控件提供明确的标签
- 验证反馈:及时提供验证错误反馈
- 默认值:为控件设置合理的默认值
- 布局合理:使用合适的控件类型和布局
性能优化
- 避免复杂计算:不要在 body 中进行复杂计算
- 使用 @State 优化:合理使用 @State 管理表单状态
- 延迟加载:对于复杂表单,考虑使用延迟加载
与 iOS 专家博客对比
根据 SwiftUI by Example 的建议:
- 使用
Section组织表单内容 - 为表单控件提供合适的键盘类型
- 利用
Form的自动布局特性 - 结合
NavigationStack构建设置页面层次
高级技巧
自定义表单样式
1struct CustomFormStyle: FormStyle { 2 func makeBody(configuration: Configuration) -> some View { 3 VStack(spacing: 0) { 4 ForEach(configuration.content) { 5 $0 6 .padding() 7 .background(Color.white) 8 .border(Color.gray.opacity(0.2), edges: .bottom) 9 } 10 } 11 .background(Color.gray.opacity(0.1)) 12 } 13} 14 15// 使用 16Form { 17 // 表单内容 18} 19.formStyle(CustomFormStyle()) 20
表单数据持久化
1import SwiftUI 2 3struct ContentView: View { 4 @AppStorage("notifications") private var notifications = true 5 @AppStorage("darkMode") private var darkMode = false 6 @AppStorage("language") private var language = "简体中文" 7 8 var body: some View { 9 NavigationStack { 10 Form { 11 Section { 12 Toggle("通知", isOn: $notifications) 13 Toggle("深色模式", isOn: $darkMode) 14 Picker("语言", selection: $language) { 15 Text("简体中文").tag("简体中文") 16 Text("English").tag("English") 17 } 18 } 19 } 20 .navigationTitle("设置") 21 } 22 } 23} 24
总结
表单与设置界面是应用中常见的组成部分,SwiftUI 提供了强大的 Form 组件来简化开发:
Form:创建结构化的表单布局- 多种内置控件:满足各种输入需求
- 实时验证:提供良好的用户反馈
- 与系统风格一致:确保视觉一致性
通过合理组织表单内容、提供清晰的验证反馈、使用适当的控件类型,可以创建出既美观又实用的设置界面。
参考资料
- SwiftUI 官方文档 - Form
- Apple Developer Documentation: TextField
- Apple Developer Documentation: Toggle
- Apple Developer Documentation: Picker
- SwiftUI by Example: Forms
本内容为《SwiftUI 进阶》第八章,欢迎关注后续更新。
《《 SwiftUI 进阶第8章:表单与设置界面》》 是转载文章,点击查看原文。