SwiftUI核心组件详解
一、Text组件 - 文本显示
基础用法
Text("Hello, SwiftUI!")
字体样式
| 属性 |
说明 |
示例 |
.font(_:) |
设置字体大小和样式 |
.font(.largeTitle) |
.fontWeight(_:) |
设置字重 |
.fontWeight(.bold) |
.foregroundColor(_:) |
设置字体颜色 |
.foregroundColor(.blue) |
.foregroundStyle(_:) |
设置前景样式(支持渐变) |
.foregroundStyle(LinearGradient(...)) |
.baselineOffset(_:) |
设置基线偏移 |
.baselineOffset(5) |
.kerning(_:) |
设置字间距(影响相邻字符) |
.kerning(2) |
.tracking(_:) |
设置字符间距(均匀分布) |
.tracking(1.5) |
.textScale(_:) |
文本缩放因子 |
. textScale(.secondary) |
文本装饰
| 属性 |
说明 |
示例 |
.underline(_:color:) |
添加下划线 |
.underline(true, color: .red) |
.strikethrough(_:color:) |
添加删除线 |
.strikethrough(true, color: .gray) |
.italic() |
设置斜体 |
.italic() |
.bold() |
设置粗体 |
.bold() |
.monospaced() |
等宽字体 |
.monospaced() |
.monospacedDigit() |
数字等宽 |
.monospacedDigit() |
排版与布局
| 属性 |
说明 |
示例 |
.lineLimit(_:) |
设置行数限制 |
.lineLimit(2) |
.truncationMode(_:) |
设置截断模式 |
.truncationMode(.tail) |
.multilineTextAlignment(_:) |
设置多行对齐方式 |
.multilineTextAlignment(.center) |
.lineSpacing(_:) |
设置行间距 |
.lineSpacing(8) |
.allowsTightening(_:) |
是否允许字符紧缩 |
.allowsTightening(true) |
.minimumScaleFactor(_:) |
最小缩放因子 |
.minimumScaleFactor(0.8) |
.textCase(_:) |
文本大小写转换 |
.textCase(.uppercase) |
多样式文本
Text("混合格式: ")
+ Text("加粗").bold()
+ Text(" + ")
+ Text("彩色").foregroundColor(.blue)
+ Text(" + ")
+ Text("大号").font(.title)
二、Image组件 - 图片显示
使用SF Symbols
Image(systemName: "star.fill")
.font(.largeTitle)
.foregroundColor(.yellow)
自定义图片
Image("my-image")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 100, height: 100)
图片效果
Image(systemName: "sun.max")
.symbolRenderingMode(.hierarchical)
.foregroundStyle(
LinearGradient(
colors: [.yellow, .orange],
startPoint: .top,
endPoint: .bottom
)
)
尺寸与缩放
| 属性 |
说明 |
示例 |
.resizable(capInsets:resizingMode:) |
允许调整图片大小 |
.resizable() |
.aspectRatio(_:contentMode:) |
控制宽高比和填充方式 |
.aspectRatio(contentMode: .fit) |
.frame(_:_:alignment:) |
设置显示尺寸 |
.frame(width: 100, height: 100) |
.scaledToFit() |
等比缩放到适合 |
.scaledToFit() |
.scaledToFill() |
等比缩放填充 |
.scaledToFill() |
.scaleEffect(_:anchor:) |
缩放效果 |
.scaleEffect(0.8) |
外观效果
| 属性 |
说明 |
示例 |
.clipShape(_:style:) |
裁剪形状 |
.clipShape(Circle()) |
.cornerRadius(_:antialiased:) |
设置圆角 |
.cornerRadius(10) |
.shadow(color:radius:x:y:) |
添加阴影 |
.shadow(color: .gray, radius: 5) |
.opacity(_:) |
设置透明度 |
.opacity(0.5) |
.blur(radius:) |
模糊效果 |
.blur(radius: 3) |
.saturation(_:) |
饱和度调整 |
.saturation(1.5) |
.brightness(_:) |
亮度调整 |
.brightness(0.2) |
.contrast(_:) |
对比度调整 |
.contrast(1.2) |
.hueRotation(_:) |
色相旋转 |
.hueRotation(.degrees(90)) |
SF Symbols 专用属性
| 属性 |
说明 |
示例 |
.symbolRenderingMode(_:) |
SF Symbols渲染模式 |
.symbolRenderingMode(.hierarchical) |
.symbolVariant(_:) |
符号变体 |
.symbolVariant(.fill) |
.foregroundStyle(_:) |
设置前景样式 |
.foregroundStyle(Color.blue) |
.font(_:) |
设置符号字体大小 |
.font(.title) |
三、Button组件 - 按钮交互
基础按钮
Button("点击我") {
print("按钮被点击")
}
带图标的按钮
// 写法1
Button(action: {
// 点击处理
}) {
Label("添加", systemImage: "plus")
}
// 写法2(苹果官方示例统一用这个)
Button{
// 点击处理
} label: {
Label("添加", systemImage: "plus")
}
提示: Label 是独立组件,不只能放在 Button 中使用,也可以单独作为内容展示:
Label("设置", systemImage: "gear") // 直接使用
自定义样式
Button {
//点击事件
} label: {
HStack(spacing: 12) {
Image(systemName: "cart")
VStack(alignment: .leading) {
Text("立即下单")
.font(.title3.bold())
}
}
.padding()
.frame(maxWidth: .infinity)
.background(.orange)
.foregroundColor(.white)
.cornerRadius(12)
}
按钮样式
| 样式 |
说明 |
示例 |
.buttonStyle(.borderedProminent) |
主要按钮(填充背景) |
默认蓝色填充 |
.buttonStyle(.bordered) |
次要按钮(边框样式) |
白色背景蓝色边框 |
.buttonStyle(.plain) |
文字按钮(无样式) |
纯文字 |
.buttonStyle(.borderless) |
无边框按钮 |
类似plain但可点击区域更大 |
.buttonStyle(.automatic) |
自动样式(根据上下文) |
系统自动选择 |
项目大量复用按钮时,自定义样式统一管理,不用重复写 padding、圆角
struct BlueButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding()
.background(configuration.isPressed ? Color.blue.opacity(0.7) : Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
.scaleEffect(configuration.isPressed ? 0.96 : 1) // 按下缩小动画
}
}
// 使用
Button {
print("点击")
} label: {
Text("自定义蓝色按钮")
}
.buttonStyle(BlueButtonStyle())
常用属性
| 属性 |
说明 |
示例 |
.tint(_:) |
设置按钮色调 |
.tint(.purple) |
.disabled(_:) |
设置禁用状态 |
.disabled(isLoading) |
.opacity(_:) |
设置透明度 |
.opacity(0.5) |
.accessibilityLabel(_:) |
无障碍标签 |
.accessibilityLabel("提交按钮") |
.accessibilityHint(_:) |
无障碍提示 |
.accessibilityHint("点击提交表单") |
.accessibilityIdentifier(_:) |
无障碍标识符 |
.accessibilityIdentifier("submitBtn") |
按钮状态
| 属性 |
说明 |
示例 |
.controlSize(_:) |
控制按钮尺寸 |
.controlSize(.large) |
.controlProminence(_:) |
控制按钮突出程度 |
.controlProminence(.increased) |
带角色的 Button:ButtonRole
iOS 15+ 新增,区分按钮语义,系统自动适配颜色 / 弹窗逻辑
可选角色:
- .cancel 取消
- .destructive 删除、危险操作(自动红色)
- .confirm 确认
- .close 关闭
// 危险删除按钮
Button(role: .destructive) {
//删除事件
} label: {
HStack {
Image(systemName: "trash")
Text("清空计数")
}
}
.buttonStyle(.borderedProminent)
四、TextField组件 - 文本输入
基础用法
@State private var text = ""
TextField("请输入文本", text: $text)
.textFieldStyle(.roundedBorder)
自定义键盘类型
TextField("邮箱", text: $email)
.keyboardType(.emailAddress)
.textInputAutocapitalization(.never) // iOS 15+ 推荐写法
搜索框
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(.secondary)
TextField("搜索...", text: $searchText)
}
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(10)
键盘配置
| 属性 |
说明 |
示例 |
.keyboardType(_:) |
设置键盘类型 |
.keyboardType(.emailAddress) |
.textInputAutocapitalization(_:) |
文本输入大写方式 |
.textInputAutocapitalization(.never) |
.autocorrectionDisabled(_:) |
是否禁用自动纠正 |
.autocorrectionDisabled(true) |
.spellCheckingDisabled(_:) |
是否禁用拼写检查 |
.spellCheckingDisabled(true) |
.textContentType(_:) |
设置文本类型(自动填充) |
.textContentType(.emailAddress) |
.returnKeyType(_:) |
设置返回键类型 |
.returnKeyType(.done) |
.enablesReturnKeyAutomatically(_:) |
是否自动启用返回键 |
.enablesReturnKeyAutomatically(true) |
输入框样式
| 属性 |
说明 |
示例 |
.textFieldStyle(_:) |
设置输入框样式 |
.textFieldStyle(.roundedBorder) |
.focused(_:) |
绑定焦点状态 |
.focused($isFocused) |
事件监听
| 属性 |
说明 |
示例 |
.onChange(of:perform:) |
内容变化监听 |
.onChange(of: text) { print($0) } |
.onSubmit(_:) |
提交时触发 |
.onSubmit { validate() } |
.onEditingChanged(_:) |
编辑状态变化 |
.onEditingChanged { isEditing in ... } |
五、SecureField组件 - 密码输入
基础用法
@State private var password = ""
SecureField("密码", text: $password)
.textFieldStyle(.roundedBorder)
带显示/隐藏切换
@State private var isSecure = true
HStack {
if isSecure {
SecureField("密码", text: $password)
} else {
TextField("密码", text: $password)
}
Button(action: { isSecure.toggle() }) {
Image(systemName: isSecure ? "eye.slash" : "eye")
}
}
.textFieldStyle(.roundedBorder)
键盘配置
| 属性 |
说明 |
示例 |
.keyboardType(_:) |
设置键盘类型 |
.keyboardType(.asciiCapable) |
.textContentType(_:) |
设置文本类型 |
.textContentType(.password) |
输入框样式
| 属性 |
说明 |
示例 |
.textFieldStyle(_:) |
设置输入框样式 |
.textFieldStyle(.roundedBorder) |
.clearButtonMode(_:) |
清除按钮显示时机 |
.clearButtonMode(.whileEditing) |
.focused(_:) |
绑定焦点状态 |
.focused($isFocused) |
事件监听
| 属性 |
说明 |
示例 |
.onSubmit(_:) |
提交时触发 |
.onSubmit { validate() } |
.onEditingChanged(_:) |
编辑状态变化 |
.onEditingChanged { isEditing in ... } |
.onChange(of:perform:) |
内容变化监听 |
.onChange(of: password) { print($0) } |
六、Toggle组件 - 开关控制
基础开关
@State private var isOn = false
Toggle("开启功能", isOn: $isOn)
自定义样式
Toggle(isOn: $darkMode) {
HStack {
Image(systemName: "moon.fill")
Text("深色模式")
}
}
.toggleStyle(SwitchToggleStyle(tint: .purple))
按钮样式开关
Toggle(isOn: $isEnabled) {
Text("启用通知")
}
.toggleStyle(.button)
开关样式
| 样式 |
说明 |
示例 |
.toggleStyle(.switch) |
开关样式 |
默认iOS开关 |
.toggleStyle(.button) |
按钮样式 |
点击切换状态 |
.toggleStyle(.checkbox) |
复选框样式 |
macOS风格 |
.toggleStyle(.switch(tint:)) |
自定义色调开关 |
.toggleStyle(SwitchToggleStyle(tint: .purple)) |
常用属性
| 属性 |
说明 |
示例 |
.toggleStyle(_:) |
设置开关样式 |
.toggleStyle(.switch) |
.labelsHidden() |
隐藏标签 |
.labelsHidden() |
.disabled(_:) |
设置禁用状态 |
.disabled(isLocked) |
.onChange(of:perform:) |
状态变化监听 |
.onChange(of: isOn) { print($0) } |
七、Slider组件 - 滑块选择
基础滑块
@State private var value = 0.5
Slider(value: $value, in: 0...1)
带范围和步进
Slider(
value: $temperature,
in: -10...40,
step: 1
) {
Text("温度")
}
带标签滑块
VStack {
Text("亮度: \(Int(brightness * 100))%")
Slider(value: $brightness, in: 0...1)
.tint(.yellow)
}
初始化参数
| 参数 |
说明 |
示例 |
value |
绑定的值 |
value: $brightness |
in |
值的范围 |
in: 0...100 |
step |
步进值 |
step: 1 |
label |
标签视图 |
label: { Text("音量") } |
minimumValueLabel |
最小值标签 |
minimumValueLabel: { Text("0") } |
maximumValueLabel |
最大值标签 |
maximumValueLabel: { Text("100") } |
常用属性
| 属性 |
说明 |
示例 |
.tint(_:) |
滑块色调 |
.tint(.blue) |
.disabled(_:) |
设置禁用状态 |
.disabled(isLocked) |
.onChange(of:perform:) |
值变化监听 |
.onChange(of: value) { print($0) } |
八、Stepper组件 - 步进控制
基础步进器
@State private var count = 0
Stepper("数量: \(count)", value: $count)
自定义范围
Stepper(
"音量: \(Int(volume * 100))%",
value: $volume,
in: 0...1,
step: 0.1
)
带图标步进器
Stepper(value: $quantity, in: 0...99) {
HStack {
Image(systemName: "cart")
Text("数量: \(quantity)")
}
}
初始化参数
| 参数 |
说明 |
示例 |
value |
绑定的值 |
value: $count |
in |
值的范围 |
in: 1...10 |
step |
步进值 |
step: 1 |
onIncrement |
增加时触发 |
onIncrement: { print("+1") } |
onDecrement |
减少时触发 |
onDecrement: { print("-1") } |
常用属性
| 属性 |
说明 |
示例 |
.disabled(_:) |
设置禁用状态 |
.disabled(isLocked) |
.labelsHidden() |
隐藏标签 |
.labelsHidden() |
.onChange(of:perform:) |
值变化监听 |
.onChange(of: count) { print($0) } |
九、Picker组件 - 选择器
基础选择器
@State private var selectedOption = "A"
Picker("选项", selection: $selectedOption) {
Text("选项 A").tag("A")
Text("选项 B").tag("B")
Text("选项 C").tag("C")
}
.pickerStyle(.segmented)
菜单样式
Picker("选择语言", selection: $language) {
Text("Swift").tag("swift")
Text("Python").tag("python")
Text("JavaScript").tag("js")
}
.pickerStyle(.menu)
滚轮样式
Picker("选择日期", selection: $day) {
ForEach(days, id: \.self) { day in
Text(day).tag(day)
}
}
.pickerStyle(.wheel)
选择器样式
| 样式 |
说明 |
适用场景 |
.pickerStyle(.segmented) |
分段控件样式 |
少量选项的横向选择 |
.pickerStyle(.menu) |
菜单样式 |
点击弹出菜单 |
.pickerStyle(.wheel) |
滚轮样式 |
大量选项的滚动选择 |
.pickerStyle(.inline) |
内联样式 |
直接显示在界面中 |
.pickerStyle(.navigationLink) |
导航链接样式 |
跳转到选择页面 |
常用属性
| 属性 |
说明 |
示例 |
.pickerStyle(_:) |
设置选择器样式 |
.pickerStyle(.segmented) |
.labelsHidden() |
隐藏标签 |
.labelsHidden() |
.disabled(_:) |
设置禁用状态 |
.disabled(isLocked) |
注意: Picker 的选中绑定是直接写在初始化器中,没有 .selection(_:) 这个 modifier。
十、DatePicker组件 - 日期选择
基础用法
@State private var selectedDate = Date()
DatePicker("选择日期", selection: $selectedDate)
日期范围
DatePicker(
"选择日期",
selection: $selectedDate,
in: Date()...,
displayedComponents: .date
)
时间选择
DatePicker(
"选择时间",
selection: $selectedDate,
displayedComponents: [.date, .hourAndMinute]
)
初始化参数
| 参数 |
说明 |
示例 |
selection |
绑定选中的日期 |
selection: $date |
in |
日期范围 |
in: Date()... |
displayedComponents |
显示的组件 |
displayedComponents: .date |
label |
标签视图 |
label: { Text("选择日期") } |
日期选择器样式
| 样式 |
说明 |
适用场景 |
.datePickerStyle(.compact) |
紧凑样式 |
节省空间 |
.datePickerStyle(.wheel) |
滚轮样式 |
传统选择方式 |
.datePickerStyle(.graphical) |
图形样式 |
日历视图 |
.datePickerStyle(.inline) |
内联样式 |
直接嵌入界面 |
显示组件类型
| 类型 |
说明 |
.date |
只显示日期 |
.hourAndMinute |
只显示时间 |
[.date, .hourAndMinute] |
同时显示日期和时间 |
常用属性
| 属性 |
说明 |
示例 |
.datePickerStyle(_:) |
设置日期选择器样式 |
.datePickerStyle(.compact) |
.labelsHidden() |
隐藏标签 |
.labelsHidden() |
.disabled(_:) |
设置禁用状态 |
.disabled(isLocked) |
十一、ColorPicker组件 - 颜色选择
基础用法
@State private var selectedColor = Color.blue
ColorPicker("选择颜色", selection: $selectedColor)
带透明度
ColorPicker("选择颜色", selection: $selectedColor, supportsOpacity: true)
初始化参数
| 参数 |
说明 |
示例 |
selection |
绑定选中的颜色 |
selection: $color |
supportsOpacity |
是否支持透明度 |
supportsOpacity: true |
label |
标签视图 |
label: { Text("选择颜色") } |
常用属性
| 属性 |
说明 |
示例 |
.labelsHidden() |
隐藏标签 |
.labelsHidden() |
.disabled(_:) |
设置禁用状态 |
.disabled(isLocked) |
十二、ProgressView组件 - 进度显示
基础进度条
ProgressView(value: progress) {
Text("加载中...")
}
圆形进度
ProgressView()
.progressViewStyle(.circular)
自定义样式
ProgressView(value: progress)
.progressViewStyle(LinearProgressViewStyle(tint: .blue))
初始化参数
| 参数 |
说明 |
示例 |
value |
当前进度值 |
value: progress |
total |
总进度值 |
total: 100 |
label |
进度标签 |
label: { Text("加载中...") } |
currentValueLabel |
当前值标签 |
currentValueLabel: { Text("\(progress)%") } |
进度条样式
| 样式 |
说明 |
示例 |
.progressViewStyle(.linear) |
线性进度条 |
默认样式 |
.progressViewStyle(.circular) |
圆形进度条 |
旋转加载 |
.progressViewStyle(.linear(tint:)) |
自定义色调线性 |
.progressViewStyle(LinearProgressViewStyle(tint: .blue)) |
常用属性
| 属性 |
说明 |
示例 |
.progressViewStyle(_:) |
设置进度条样式 |
.progressViewStyle(.circular) |
.tint(_:) |
进度条色调 |
.tint(.green) |
.opacity(_:) |
设置透明度 |
.opacity(0.8) |
十三、List组件 - 列表展示
基础列表
List {
Text("第一项")
Text("第二项")
Text("第三项")
}
使用ForEach
let items = ["苹果", "香蕉", "橙子"]
List(items, id: \.self) { item in
Text(item)
}
分组列表
List {
Section("水果") {
Text("苹果")
Text("香蕉")
}
Section("蔬菜") {
Text("胡萝卜")
Text("西兰花")
}
}
可选择列表
struct SelectableList: View {
let items = ["选项1", "选项2", "选项3"]
@State private var selectedItem: String?
var body: some View {
// 方式1:点击选中(常用)
List {
ForEach(items, id: \.self) { item in
Text(item)
.onTapGesture {
selectedItem = item
}
.background(selectedItem == item ? Color.accentColor.opacity(0.2) : Color.clear)
}
}
}
}
// 方式2:编辑模式选中(selection 参数仅在编辑模式生效)
struct EditModeList: View {
let items = ["选项1", "选项2", "选项3"]
@State private var selectedItem: String?
@Environment(\.editMode) private var editMode
var body: some View {
List(items, id: \.self, selection: $selectedItem) { item in
Text(item)
}
.toolbar {
EditButton() // 需要编辑按钮才能启用 selection
}
}
}
重要提示: List 的 selection 参数只在编辑模式(EditButton)下生效,不是普通的点击选中。普通点击选中需要使用 .onTapGesture。
列表样式
| 样式 |
说明 |
适用场景 |
.listStyle(.plain) |
简洁样式 |
普通列表 |
.listStyle(.insetGrouped) |
分组样式 |
设置页面 |
.listStyle(.sidebar) |
侧边栏样式 |
导航侧边栏 |
.listStyle(.grouped) |
分组样式(iOS 14及以下) |
旧版系统 |
.listStyle(.inset) |
内嵌样式 |
紧凑列表 |
.listStyle(.carousel) |
轮播样式(iOS 17+) |
横向轮播展示 |
行配置属性
| 属性 |
说明 |
示例 |
.listRowBackground(_:) |
设置行背景 |
.listRowBackground(Color.blue) |
.listRowSeparator(_:edges:) |
设置行分隔线 |
.listRowSeparator(.hidden) |
.listRowSeparatorTint(_:) |
设置分隔线颜色 |
.listRowSeparatorTint(.gray) |
.listRowInsets(_:) |
设置行内边距 |
.listRowInsets(EdgeInsets()) |
.listRowAlignment(_:) |
设置行对齐方式 |
.listRowAlignment(.leading) |
分组配置属性
| 属性 |
说明 |
示例 |
.listSectionSeparator(_:edges:) |
设置分组分隔线 |
.listSectionSeparator(.hidden) |
.listSectionSeparatorTint(_:) |
设置分组分隔线颜色 |
.listSectionSeparatorTint(.gray) |
.listSectionSpacing(_:) |
设置分组间距 |
.listSectionSpacing(20) |
常用属性
| 属性 |
说明 |
示例 |
.listStyle(_:) |
设置列表样式 |
.listStyle(.plain) |
.scrollIndicators(_:) |
设置滚动指示器 |
.scrollIndicators(.hidden) |
.onDelete(perform:) |
删除操作 |
.onDelete { indices in ... } |
.onMove(perform:) |
移动操作 |
.onMove { source, destination in ... } |
注意: List 的 selection 参数是直接写在初始化器中(List(selection: $selected)),且只在编辑模式(EditButton)下生效。普通点击选中请使用 .onTapGesture。
十四、Form组件 - 表单布局
基础表单
Form {
Section {
TextField("用户名", text: $username)
SecureField("密码", text: $password)
}
Section {
Toggle("记住我", isOn: $rememberMe)
}
Section {
Button("登录") {
// 登录逻辑
}
}
}
表单控件组合
Form {
Section {
TextField("姓名", text: $name)
TextField("邮箱", text: $email)
.keyboardType(.emailAddress)
DatePicker("出生日期", selection: $birthDate)
}
Section {
Slider(value: $volume, in: 0...1) {
Text("音量")
}
Stepper("数量: \(quantity)", value: $quantity, in: 1...10)
}
}
表单样式
| 样式 |
说明 |
适用场景 |
.formStyle(.grouped) |
分组样式 |
设置页面 |
.formStyle(.columns) |
多列样式 |
iPad分栏布局 |
常用属性
| 属性 |
说明 |
示例 |
.formStyle(_:) |
设置表单样式 |
.formStyle(.grouped) |
.listStyle(_:) |
设置内部列表样式 |
.listStyle(.insetGrouped) |
.scrollContentBackground(_:) |
设置滚动背景(iOS 16+) |
.scrollContentBackground(.hidden) |
Section 属性
| 属性 |
说明 |
示例 |
header |
分组头部 |
header: Text("基本信息") |
footer |
分组尾部 |
footer: Text("请填写真实信息") |
.headerProminence(_:) |
头部突出程度 |
.headerProminence(.increased) |
十五、NavigationStack - 导航容器
基础导航
NavigationStack {
List(items) { item in
NavigationLink(value: item) {
Text(item.name)
}
}
.navigationDestination(for: Item.self) { item in
DetailView(item: item)
}
.navigationTitle("标题")
}
导航栏样式
NavigationStack {
// 内容
}
.navigationBarTitleDisplayMode(.large) // 大标题
.navigationBarTitleDisplayMode(.inline) // 行内标题
工具栏
NavigationStack {
List { ... }
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("返回") { }
}
ToolbarItem(placement: .navigationBarTrailing) {
Button("保存") { }
}
}
}
标题配置
| 属性 |
说明 |
示例 |
.navigationTitle(_:) |
设置导航标题 |
.navigationTitle("首页") |
.navigationBarTitleDisplayMode(_:) |
设置标题显示模式 |
.navigationBarTitleDisplayMode(.large) |
.navigationBarHidden(_:) |
隐藏导航栏 |
.navigationBarHidden(true) |
导航目标
| 属性 |
说明 |
示例 |
.navigationDestination(for:destination:) |
设置目标视图 |
.navigationDestination(for: Item.self) { ... } |
.navigationBarBackButtonHidden(_:) |
隐藏返回按钮 |
.navigationBarBackButtonHidden(true) |
注意: .navigationBarItems(leading:trailing:) 已在 iOS 15+ 废弃,统一使用 .toolbar 替代。
工具栏配置
| 属性 |
说明 |
示例 |
.toolbar(_:content:) |
设置工具栏 |
.toolbar { ... } |
.toolbarRole(_:) |
设置工具栏角色 |
.toolbarRole(.navigationStack) |
.toolbarBackground(_:for:) |
设置工具栏背景 |
.toolbarBackground(.visible, for: .navigationBar) |
.toolbarColorScheme(_:for:) |
设置工具栏配色 |
.toolbarColorScheme(.dark, for: .navigationBar) |
十六、TabView - 标签页视图
基础标签页
TabView {
HomeView()
.tabItem {
Image(systemName: "house")
Text("首页")
}
SearchView()
.tabItem {
Image(systemName: "magnifyingglass")
Text("搜索")
}
ProfileView()
.tabItem {
Image(systemName: "person")
Text("我的")
}
}
带选中状态
TabView(selection: $selectedTab) {
HomeView()
.tabItem {
Image(systemName: "house")
Text("首页")
}
.tag(0)
SearchView()
.tabItem {
Image(systemName: "magnifyingglass")
Text("搜索")
}
.tag(1)
}
TabView样式
| 样式 |
说明 |
适用场景 |
.tabViewStyle(.page) |
页面滚动样式 |
轮播图 |
.tabViewStyle(.tabBar) |
底部标签栏样式 |
应用主界面 |
常用属性
| 属性 |
说明 |
示例 |
.tabViewStyle(_:) |
设置标签页样式 |
.tabViewStyle(.page) |
.indexViewStyle(_:) |
设置页码指示器样式 |
.indexViewStyle(.page(backgroundDisplayMode: .always)) |
.onChange(of:perform:) |
标签页切换监听 |
.onChange(of: selectedTab) { print($0) } |
注意: TabView 的选中绑定是直接写在初始化器中(TabView(selection: $selectedTab)),没有 .selection(_:) 这个 modifier。
TabItem 配置
| 属性 |
说明 |
示例 |
.tag(_:) |
设置标签标识 |
.tag(0) |
.badge(_:) |
设置角标 |
.badge(3) |
十七、布局组件
VStack - 垂直布局
VStack(alignment: .leading, spacing: 8) {
Text("第一行")
Text("第二行")
Text("第三行")
}
HStack - 水平布局
HStack(alignment: .center, spacing: 12) {
Image(systemName: "star")
Text("评分")
Spacer()
Text("5.0")
}
ZStack - 层叠布局
ZStack {
Circle()
.fill(Color.blue)
.frame(width: 100, height: 100)
Image(systemName: "checkmark")
.foregroundColor(.white)
.font(.title)
}
Spacer - 空白填充
HStack {
Text("左对齐")
Spacer() // 占据中间所有空间
Text("右对齐")
}
Divider - 分隔线
VStack {
Text("上方内容")
Divider()
Text("下方内容")
}
VStack 属性
| 属性 |
说明 |
示例 |
alignment |
子视图水平对齐方式 |
alignment: .leading |
spacing |
子视图垂直间距 |
spacing: 16 |
content |
子视图内容 |
@ViewBuilder content |
HStack 属性
| 属性 |
说明 |
示例 |
alignment |
子视图垂直对齐方式 |
alignment: .center |
spacing |
子视图水平间距 |
spacing: 12 |
content |
子视图内容 |
@ViewBuilder content |
ZStack 属性
| 属性 |
说明 |
示例 |
alignment |
子视图对齐方式 |
alignment: .topTrailing |
content |
子视图内容(层叠) |
@ViewBuilder content |
LazyVStack & LazyHStack
核心特性:懒加载
- 屏幕外的视图不会被创建,只有滚动到可见区域时才会创建
- 滚动性能更高,适合大量数据列表
-
LazyVStack 垂直懒加载,LazyHStack 水平懒加载
// 示例:高效展示大量数据
ScrollView {
LazyVStack {
ForEach(0..<1000) { index in
Text("项目 \(index)")
.frame(height: 50)
}
}
}
| 属性 |
说明 |
示例 |
alignment |
子视图对齐方式 |
alignment: .leading |
spacing |
子视图间距 |
spacing: 8 |
pinnedViews |
固定视图(如Header) |
pinnedViews: [.sectionHeaders] |
Spacer 属性
| 属性 |
说明 |
示例 |
minLength |
最小长度 |
minLength: 20 |
Divider 属性
| 属性 |
说明 |
示例 |
.foregroundColor(_:) |
分隔线颜色 |
.foregroundColor(.gray) |
十八、自定义组件
创建可复用组件
struct FeatureCard: View {
let icon: String
let title: String
let description: String
var body: some View {
VStack(spacing: 8) {
Image(systemName: icon)
.font(.title)
.foregroundColor(.blue)
Text(title)
.font(.headline)
Text(description)
.font(.caption)
.foregroundColor(.secondary)
}
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(12)
}
}
// 使用
FeatureCard(
icon: "star",
title: "功能标题",
description: "功能描述"
)
使用@ViewBuilder自定义容器
struct CardContainer<Content: View>: View {
let content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
VStack {
content
}
.padding()
.background(Color.white)
.cornerRadius(16)
.shadow(radius: 4)
}
}
// 使用
CardContainer {
Text("卡片内容")
Button("点击") { }
}
十九、组件组合示例
完整表单示例
struct LoginView: View {
@State private var email = ""
@State private var password = ""
@State private var rememberMe = false
var body: some View {
VStack(spacing: 20) {
Image(systemName: "person.circle")
.font(.system(size: 64))
.foregroundColor(.blue)
TextField("邮箱", text: $email)
.textFieldStyle(.roundedBorder)
SecureField("密码", text: $password)
.textFieldStyle(.roundedBorder)
Toggle(isOn: $rememberMe) {
Text("记住我")
}
Button("登录") {
// 登录逻辑
}
.buttonStyle(.borderedProminent)
.tint(.blue)
}
.padding()
}
}
完整列表示例
struct ContactRow: View {
let contact: Contact
var body: some View {
HStack(spacing: 12) {
Image(systemName: "person.circle")
.font(.title)
VStack(alignment: .leading, spacing: 4) {
Text(contact.name)
.font(.headline)
Text(contact.phone)
.font(.caption)
.foregroundColor(.secondary)
}
Spacer()
Image(systemName: "chevron.right")
.foregroundColor(.secondary)
}
}
}
二十、Alert组件 - 警告弹窗
基础用法
@State private var showAlert = false
Button("显示警告") {
showAlert = true
}
.alert("提示", isPresented: $showAlert) {
Button("确定", role: .cancel) { }
}
带多个按钮
.alert("确认删除", isPresented: $showAlert) {
Button("取消", role: .cancel) { }
Button("删除", role: .destructive) {
// 执行删除
}
} message: {
Text("此操作不可撤销")
}
Alert 属性
| 属性 |
说明 |
示例 |
title |
标题 |
title: Text("警告") |
isPresented |
显示状态绑定 |
isPresented: $showAlert |
message |
详细信息 |
message: { Text("详细说明") } |
actions |
按钮操作 |
actions: { Button("确定") {} } |
按钮角色
| 角色 |
说明 |
示例 |
.cancel |
取消按钮 |
Button("取消", role: .cancel) |
.destructive |
破坏性操作 |
Button("删除", role: .destructive) |
.none |
默认角色 |
Button("确定", role: .none) |
二十一、Sheet组件 - 模态表单
基础用法
@State private var showSheet = false
Button("打开详情") {
showSheet = true
}
.sheet(isPresented: $showSheet) {
DetailView()
}
带数据传递
@State private var selectedItem: Item?
.sheet(item: $selectedItem) { item in
DetailView(item: item)
}
Sheet 属性
| 属性 |
说明 |
示例 |
isPresented |
显示状态绑定 |
isPresented: $showSheet |
item |
绑定可选数据 |
item: $selectedItem |
content |
内容视图 |
content: { DetailView() } |
onDismiss |
关闭回调 |
onDismiss: { print("已关闭") } |
.presentationDetents(_:) |
设置高度模式 |
.presentationDetents([.medium, .large]) |
.presentationDragIndicator(_:) |
拖拽指示器 |
.presentationDragIndicator(.visible) |
高度模式
| 模式 |
说明 |
.medium |
中等高度(约一半) |
.large |
全屏高度 |
.fraction(_:) |
按比例高度 |
.height(_:) |
固定高度 |
二十二、Shape组件 - 图形绘制
Circle - 圆形
Circle()
.fill(Color.blue)
.frame(width: 100, height: 100)
Rectangle - 矩形
Rectangle()
.fill(Color.red)
.frame(width: 200, height: 100)
RoundedRectangle - 圆角矩形
RoundedRectangle(cornerRadius: 16)
.fill(Color.green)
.frame(width: 200, height: 100)
Ellipse - 椭圆
Ellipse()
.fill(Color.purple)
.frame(width: 150, height: 80)
Capsule - 胶囊形状
Capsule()
.fill(Color.orange)
.frame(width: 100, height: 40)
Shape 常用属性
| 属性 |
说明 |
示例 |
.fill(_:) |
填充颜色 |
.fill(Color.blue) |
.stroke(_:lineWidth:) |
描边 |
.stroke(Color.red, lineWidth: 2) |
.strokeBorder(_:lineWidth:) |
内描边 |
.strokeBorder(Color.red, lineWidth: 2) |
.frame(width:height:) |
设置尺寸 |
.frame(width: 100, height: 100) |
.trim(from:to:) |
裁剪部分 |
.trim(from: 0, to: 0.5) |
.rotationEffect(_:) |
旋转 |
.rotationEffect(.degrees(45)) |
.offset(_:) |
偏移 |
.offset(CGSize(width: 10, height: 10)) |
Path - 自定义路径
Path { path in
path.move(to: CGPoint(x: 10, y: 10))
path.addLine(to: CGPoint(x: 100, y: 10))
path.addLine(to: CGPoint(x: 100, y: 100))
path.closeSubpath()
}
.stroke(Color.blue, lineWidth: 2)
二十三、动画组件 - 动画效果
withAnimation - 显式动画
Button("动画") {
withAnimation(.spring()) {
isExpanded.toggle()
}
}
animation - 隐式动画
Circle()
.frame(width: isLarge ? 100 : 50)
.animation(.easeInOut, value: isLarge)
动画类型
重要提示: iOS 15+ 推荐使用带 value 参数的 .animation(),避免诡异的动画效果。
| 类型 |
说明 |
示例 |
.default |
默认动画 |
.animation(.default, value: state) |
.linear |
线性动画 |
.animation(.linear, value: state) |
.easeIn |
缓入动画 |
.animation(.easeIn, value: state) |
.easeOut |
缓出动画 |
.animation(.easeOut, value: state) |
.easeInOut |
缓入缓出 |
.animation(.easeInOut, value: state) |
.spring() |
弹簧动画 |
.animation(.spring(), value: state) |
.bouncy() |
弹跳动画(iOS 17+) |
.animation(.bouncy(), value: state) |
.smooth() |
平滑动画(iOS 17+) |
.animation(.smooth(), value: state) |
.interactiveSpring() |
交互弹簧 |
.animation(.interactiveSpring(), value: state) |
弹簧动画参数
| 参数 |
说明 |
示例 |
mass |
质量 |
.spring(mass: 1.0) |
stiffness |
刚度 |
.spring(stiffness: 100) |
damping |
阻尼 |
.spring(damping: 10) |
duration |
持续时间 |
.spring(duration: 0.5) |
transition - 过渡动画
if showView {
Text("Hello")
.transition(.slide)
}
过渡类型
| 类型 |
说明 |
示例 |
.identity |
无过渡 |
.transition(.identity) |
.opacity |
透明度过渡 |
.transition(.opacity) |
.scale |
缩放过渡 |
.transition(.scale) |
.slide |
滑动过渡 |
.transition(.slide) |
.push(from:) |
推入过渡 |
.transition(.push(from: .leading)) |
.move(edge:) |
移动过渡 |
.transition(.move(edge: .bottom)) |
.asymmetric(insertion:removal:) |
非对称过渡 |
.transition(.asymmetric(insertion: .slide, removal: .opacity)) |
matchedGeometryEffect - 共享元素过渡
@Namespace private var namespace
// 源视图
Image("photo")
.matchedGeometryEffect(id: "photo", in: namespace)
// 目标视图
Image("photo")
.matchedGeometryEffect(id: "photo", in: namespace)