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