《 SwiftUI 进阶第8章:表单与设置界面》

作者:90后晨仔日期:2026/4/18

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

最佳实践

  1. 分组逻辑:按照功能将表单控件分组
  2. 标签清晰:为每个控件提供明确的标签
  3. 验证反馈:及时提供验证错误反馈
  4. 默认值:为控件设置合理的默认值
  5. 布局合理:使用合适的控件类型和布局

性能优化

  1. 避免复杂计算:不要在 body 中进行复杂计算
  2. 使用 @State 优化:合理使用 @State 管理表单状态
  3. 延迟加载:对于复杂表单,考虑使用延迟加载

与 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 进阶》第八章,欢迎关注后续更新。


《 SwiftUI 进阶第8章:表单与设置界面》》 是转载文章,点击查看原文


相关推荐


OpenClaw(龙虾)最强开源对手!Github 40K Star了,又一个爆火的Agent..
AI袋鼠帝2026/4/10

大家好,我是袋鼠帝。 最近几天,不管是国内的开发者社群,还是国外的X,又有一个开源项目的热度简直高得离谱。 根据开源项目飙升榜的数据,它在一个月内的增长率达到了惊人的百分之1237。 仅仅过了两个月时间,它的标星数量就已经突破了40k大关。 在技术社区里,很多人甚至直接把它称为OpenClaw的第一个真正竞争对手。 这个爆火的开源项目,叫做 Hermes Agent,地址 github.com/NousResearc… 是由 Nous Research 团队倾力打造的开源Agent。 今


在 Debian 上部署 ELK 7.17 完整指南
itmanll2026/4/2

Elasticsearch 7.17 是 7.x 系列的最终维护版本,目前仍有大量生产环境集群运行此版本。本指南将详细介绍如何在 Debian 12/13 上完整部署 ELK 7.17 栈(Elasticsearch、Logstash、Kibana)。 环境要求 Debian 12(bookworm)或 Debian 13(trixie)至少 4GB 内存(默认堆内存占用约 2.4GB)开放端口:9200(Elasticsearch HTTP)、9300(Elasticsearch 传输)


【35天从0开始备战蓝桥杯 -- Day5】
小年糕是糕手2026/3/24

🫧个人主页:小年糕是糕手 💫个人专栏:《C++》《Linux》《数据结构》《C语言》 🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来! 目录 一、输入输出 1.1、单组测试用例 1°计算 (a+b)/c 的值 2°与 7 无关的数 1.2、多组测试用例 情况一 1°多组输入a+b II 2°斐波那契数列 3°制糊串 情况二 1°多组输入a+b 2°数字三角形 3°定位查找 情况三 1°字符统计 拓展函数 2°多组数据


OpenClaw“小龙虾”深度解析:60天碾压Linux的AI智能体,从原理到搞定本地部署【Windows系统 + 接入飞书】
燃于AC之乐2026/3/16

👇点击进入作者专栏: 《算法画解》 ✅ 《linux系统编程》✅ 《C++》 ✅ OpenClaw“小龙虾”深度解析:60天碾压Linux的AI智能体,从原理到搞定本地部署【Windows系统 + 接入飞书】 引言:2026年最火爆的开源AI智能体一、OpenClaw是什么?——从“对话”到“动手”的质变1.1 核心定位:长了手脚的大模型1.2 核心能力:一键控制电脑 二、技术原理:AI如何真正“动手干活”?2.1 架构设计2.2 工作流程2.3 技术关键点:上下文窗口压


dt/dd表格解析、URL拼接缺失、ON DUPLICATE字段覆盖、CSS选择器定位——俄罗斯轮胎展爬虫四大技术难关攻克纪实
进击的雷神2026/3/8

一、引言 在俄罗斯展会网站采集中,莫斯科轮胎及橡胶展览会(Expocentr)的网站采用了典型的表格布局和dt/dd结构存储展商信息。本文以该展会参展商信息采集项目为例,深入剖析在开发过程中遇到的四大技术难题,以及我们如何通过创新的技术方案逐一攻克这些难关。 二、技术难点全景图 #mermaid-svg-T86ttY9To1T8fJpx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill


三月,我只想做好这四件事
修己xj2026/2/28

今天是二月的最后一天,也是春节后上班第一周的收官之日。 在我们中国人的观念里,只有过完春节,新的一年才算真正开始。往年的这个时候,我总会兴致勃勃地立下一堆flag,制定满满当当的年度计划。虽然年终盘点时发现大部分都没实现,但来年依旧乐此不疲——仿佛只要把计划写得够漂亮,生活就会自动变好。 但今年不一样了。 家里添了一位新成员,我的身份悄然发生了改变。抱着怀里这个两个月大的小家伙,我突然不想再立那些宏大的flag,也不想做那些看似充实却往往落空的计划了。 一年很长,长到要数着日历过365个日夜;


C# WPF canvas中绘制缺陷分布map并实现缩放
zls3653652026/2/19

1、前台xaml 这里把canvas包裹在scrollviewer里面是为了避免滚轮缩放时canvas超出划定的区域,导致显示异常。 2. 后台代码: -. canvas load事件,主要用来获取控件的长度和宽度 -. canvas_mousewheel(object sender,MouseWheelEventArgs e)这个事件主要功能是为了实现通过鼠标进行canvas控件的缩放 -. 这里的逻辑主要为了实现缺陷分布图上的缺陷通过x进行标注 -.深度拷


AI 视觉连载3:RGB与通道
董章鱼是个攻城狮2026/2/11

在2、灰度与色彩的最后,给出了一个由彩色图片转成灰度图的示例,并且通过 color_image.mode获取了图片的格式:彩色图片获取到的格式为 RGBA,灰度图为 L。 这一节再介绍一下 RGB 图片以及通道的概念。 通道这个概念,在 深度学习 中很重要,并且极为重要。 举个例子—— 在很多时候,对AI神经网络中的一些算法做工程化实现,或者做性能优化,除了关注算法本身之外,还会关注数据存储格式。 一般在 pytorch 中(一个AI模型框架),数据的存储格式 NCHW, C指代的就是通道(ch


自组织特征映射(SOM)的数据聚类程序。 matlab程序 数据格式为excel
NBhhbYyOljP2026/2/2

自组织特征映射(SOM)的数据聚类程序。 matlab程序 数据格式为excel。 打开MATLAB准备搞点数据魔法?今天咱们整点有意思的——用自组织特征映射(SOM)给Excel数据自动分群。这玩意儿就像给数据画美食地图,让相似的样本自动抱团取暖。 先来点准备工作。把Excel数据塞进MATLAB最直接的方式就是readtable函数: data = readtable('你的数据.xlsx'); raw_data = table2array(data(:,2:end)); % 假设第


iOS 常用调试工具大全-打造你的调试武器库
sweet丶2026/1/24

还记得你第一次使用NSLog(@"Hello, World!")的时刻吗?那是调试的起点。但随着应用复杂度呈指数级增长,我们需要的工具也经历了革命性进化: 第一代:基础输出(NSLog、print) 第二代:图形化界面(Xcode调试器、Instruments) 第三代:运行时动态调试(FLEX、Lookin) 第四代:智能化监控(性能追踪、自动化检测) 今天,一个成熟的iOS开发者工具箱中,至少需要掌握3-5种核心调试工具,它们就像外科医生的手术刀——精准、高效、各有所长。 一、运行时调试

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客