表单
导航栏
提示:很容易认为修饰符应该附加到 NavigationStack的末尾,但实际上是附加到Form的末尾。原因是导航堆栈能够在程序运行时显示许多视图,因此通过将标题附加到导航堆栈内的内容,我们允许 iOS 自由更改标题。
- toolbar 工具栏
toolbar()让我们可以指定视图的工具栏项。这些工具栏项可能出现在屏幕上的各个位置 - 顶部的导航栏中、底部的特殊工具栏区域等。
- onChange 监听属性变化
.onChange(of: xxx ) { oldValue, newValue in
// 特定值发生变化,它就会运行我们选择的闭包
}
按钮 & 属性包装器 @State
Button("删除", action: executeDelete)
Button("删除", role: .destructive) {
...
}
.buttonStyle(.borderedProminent) // 样式风格
.tint(.blue) // 颜色
Button("编辑", systemImage: "pencil") {
//...
}
自定义按钮
Button {
//...
} label: {
// 自定义控件 样式 布局
Label("Edit", systemImage: "pencil")
.padding()
.foregroundStyle(.white)
.background(.red)
}
- 更改属性
由于Swift的结构体是值类型(固定的),不允许修改其属性。若要更改属性,Swift提供了@State允许我们这个限制:@State允许 SwiftUI 将该值单独存储在可以修改的位置。
@State 会自动监视更改,并且当发生某些情况时它会自动重新调用该body属性。它将重新加载您的 UI 以反映更改后的状态,这是 SwiftUI 工作方式的基本功能。
@State专为存储在一个视图中的简单属性而设计。Apple 建议我们为这些属性添加访问控制private。
当然,我们可以使用类来代替———它们可以自由修改属性。但是,SwiftUI 会频繁地销毁和重新创建您的结构体,因此保持它们小而简单对于性能非常重要。使用结构体是 出于性能的考虑。
文本框 & 双向绑定
- 视图是其状态的函数
- 双向绑定
使用符号$和 @State 组合
输入框绑定文本属性 => 输入框显示文本属性,同时,输入框编辑也会更新属性。
我们在属性名前写一个美元符号。这告诉 Swift 它应该读取属性的值,但也应该在发生任何更改时将其写回。
- 格式
- 键盘的隐藏
需要用到第二个属性包装器:@FocusState。这与常规的@State完全相同,只不过它是专门为处理 UI 中的输入焦点而设计的。
在循环中创建视图 ForEach
想要在循环内创建多个 SwiftUI 视图是很常见的。例如,想要循环遍历一组名称,并让每个名称都是一个文本视图。SwiftUI 为此目的提供了一个专用的视图类型,称为ForEach。 这可以循环数组和范围,根据需要创建尽可能多的视图。ForEach将为它循环的每个项目运行一次闭包,并传入当前循环项目。
选择器 Picker
其中,id: \.self部分很重要。因为 SwiftUI 需要能唯一地识别屏幕上的每个视图,以便它可以检测到事物何时发生变化。这里,id: \.self意味着“字符串本身是唯一的”,如果您向options数组添加重复的字符串,可能会遇到问题
- 设置风格
堆栈视图
VStack 垂直排列布局
- 间距
VStack(spacing: 30){
}
- 对齐方式
VStack(alignment: .leading) {
}
- Spacer() 占用/排挤
将堆栈的内容推到一侧。可添加多个
HStack 水平排列布局
同理
ZStack 重叠布局
按深度排列控件——它使视图重叠。
没有间距的概念,因为视图重叠,但它确实有对齐。
颜色
SwiftUI 为我们提供了一系列渲染颜色的功能,并且做到了既简单又强大。
- 安全区域
白色空间为故意留空,因为 Apple 不希望重要内容被其他 UI 功能或设备上的任何圆角遮挡。所以,剩下的部分——整个中间的空间——被称为 “安全区域”,你可以自由地绘制它,而不用担心它可能被 iPhone 上的凹口剪掉。 白色空间的大小取决于您的设备,但在具有 Face ID 的 iPhone(例如 iPhone 15)上,您会发现动态岛区域(顶部的胶囊形区域)和主页指示器(水平方向)底部的条纹)保持未着色。
如果需要,你可以设置忽略安全区
重要的内容不要放置在安全区域之外,这一点至关重要。如果您的内容只是装饰性的(就像我们这里的背景颜色一样),那么将其扩展到安全区域之外是可以的。
- frame
颜色会自动占据所有可用空间,但您也可以使用修饰符frame()来请求特定尺寸;还可以根据所需的布局指定最小和最大宽度和高度。
Color.red
.frame(width: 200, height: 200)
Color.red
.frame(minWidth: 200, maxWidth: .infinity, maxHeight: 200)
事实上,Color.red 本身就是一个视图,这就是为什么它可以像形状和文本一样使用。
- 内置颜色
如Color.blue、Color.green、Color.indigo
- 语义颜色
颜色不说明它们包含什么色调,而是描述它们的用途。
如,Color.primary是 SwiftUI 中文本的默认颜色,并且将是黑色或白色,具体取决于用户的设备是在浅色模式还是深色模式下运行。还有Color.secondary,根据设备的不同,它也是黑色或白色,但现在具有轻微的透明度,因此其背后的一些颜色会透过。
- 自定义颜色
Color(red: 1, green: 0.8, blue: 0)
- 渐变
SwiftUI 为我们提供了 四种 可供使用的渐变,就像颜色一样,它们中的大多数也是可以在我们的 UI 中绘制的视图。
渐变由几个部分组成:
- 显示一系列颜色
- 尺寸和方向信息
- 要使用的渐变类型
一、线性渐变:朝一个方向移动
LinearGradient(colors: [.white, .black], startPoint: .top, endPoint: .bottom)
可以提供渐变停止点,让您指定颜色以及颜色应该沿渐变多远使用
LinearGradient(stops: [
.init(color: .white, location: 0.45),
.init(color: .black, location: 0.55),
], startPoint: .top, endPoint: .bottom)
二、径向渐变:以圆形形状向外移动。因此我们不指定方向,而是指定开始和结束半径——颜色应开始和停止变化距离圆心多远。
RadialGradient(colors: [.blue, .white], center: .center, startRadius: 20, endRadius: 200)
三、角度渐变,(圆锥形或圆锥形渐变)
这样颜色会围绕一个圆圈循环,而不是向外辐射,并且可以产生一些美丽的效果。
AngularGradient(colors: [.red, .yellow, .green, .blue, .purple, .red], center: .center)
四、渐变背景
您无法对其进行任何控制,并且您也只能将它们用作背景和前景样式,而不是单独的视图。 只需在任何颜色后添加即可创建此渐变.gradient
弹窗
状态属性控制弹窗。提示:双向数据绑定,当警报解除时 SwiftUI 会自动设置回 false,不需要手动处理。
小技巧
- 数组
var arr = [2,6,4,8,9,3]
arr.shuffled() // 进行 数组随机排序
- 文本
// 粗体
Text("提示").font(.subheadline.weight(.heavy))
// 大标题
Text("提示").font(.largeTitle.weight(.semibold))
// 小标题
Text("提示").font(.title3.weight(.bold))
- 圆角处理
.clipShape(.capsule) // 胶囊
.clipShape(.rect(cornerRadius: 10)) // 圆角
- 阴影处理
.shadow(radius: 12)
- 最大宽高
.frame(maxWidth: .infinity, maxHeight: .infinity)