Swift UI笔记
简介
Swift UI是苹果系统的一个跨平台iOS、Mac OS、TV OS、iPad OS、Watch OS的UI框架。将成为苹果生态UI开发的基础。
在Swift UI中,View协议将代替iOS开发的UIView、Mac OS的NSView成为UI开发的基础。
SwiftUI有以下好处:
- 将数据和视图进行完全地解耦
- 更方便地管理依赖
SwiftUI可以实现UI开发中的: - 布局
- 图案
- 动画和切换
- 交互
SwiftUI可定制的图形特效: - 透明度
- 几何属性 (旋转、缩放等)
- 颜色
- 模糊
- 阴影效果
- 裁剪、遮罩
- 组合、分组、混合模式
构建UI
Hello world
struct ContentView : View {
var body: some View {
Text(“Hello World”)
}
}
设置视图大小
struct TrippyBadge : View {
var body: some View {
Image("ColorWash").frame(width: 50, height: 10)
}
}
设置背景颜色
struct Toast : View {
var body: some View {
Text("Avocado Toast")
} .background(Color.green)
}
添加边距
struct Toast : View {
var body: some View {
Text("Avocado Toast").padding([.leading, .trailing]) .background(Color.green)
}
}
或者
struct Toast : View {
var body: some View {
Text("Avocado Toast").padding(10).background(Color.green)
}
}
或者
struct Toast : View {
var body: some View {
Text("Avocado Toast").padding().background(Color.green)
}
}
使用HStack和VStack进行UI布局
HStack {
VStack {
Text("")
Text("5 stars")
}.font(.caption)
VStack(alignment: .leading) {
HStack {
Text("Avocado Toast").font(.title)
Spacer()
Image("20x20_avocado")
}
Text("Ingredients: Avocado, Almond Butter, Bread, Red Pepper Flakes").font(.caption).lineLimit(1)
}
}
设置多个控件在一行
HStack {
Text("Delicious")
Image("20x20_avocado")
Text("Avocado Toast")
}.lineLimit(1)
绑定状态变量
struct RoomDetail: View {
let room: Room
@State private var zoomed = false
var body: some View {
Image(room.imageName).resizable().aspectRatio(contentMode: zoomed ? .fill : .fit).tapAction {
self.zoomed.toggle()
}
}
}
使用NavigationButton控制导航
NavigationButton(destination: RoomDetail(room: room)) {
Image(room.thumbnailName) .cornerRadius(8)
VStack(alignment: .leading) {
Text(room.name)
}
Text(”\(room.capacity) people”).font(.footnote).foregroundColor(.secondary)
}
绘图
你可以使用Circle、Capsule、Ellipse等形状进行fill、stroke、strokeBorder等操作。
绘制形状
struct ReadCircle: View {
Circle().fill(Color.red)
}
绘制水平梯度
struct GradientView: View {
var body: some View {
let spectrum = Gradient(colors[.red, .yellow, .green, .cyan, .blue, .purple, .red ])
}
}
绘制锥形梯度
struct GradientView: View {
var body: some View {
let spectrum = Gradient(colors: [.red, .yellow, .green, .cyan, .blue, .purple, .red ])
let conic = AngularGradient(gradient: spectrum, center: .center, angle: .degrees(-90))
}
}
变成圆形
struct GradientView: View {
var body: some View {
let spectrum = Gradient(colors: [ .red, .yellow, .green, .cyan, .blue, .purple, .red
])
let conic = AngularGradient(gradient: spectrum, center: .center, angle: .degrees(-90))
return Circle().fill(conic)
}
}
变成圆环
struct GradientView: View {
var body: some View {
let spectrum = Gradient(colors: [
.red, .yellow, .green, .cyan, .blue, .purple, .red ])
let conic = AngularGradient(gradient: spectrum, center: .center, angle: .degrees(-90))
return Circle().strokeBorder(conic, lineWidth: 50) }
}
自定义形状
class Ring {
struct Wedge {
var width: Double var depth: Double var hue: Double
}
var wedges: [Int: Wedge]
var wedgeIDs: [Int]
}
struct WedgeShape: Shape {
var wedge: Ring.Wedge
func path(in rect: CGRect) -> Path {
var p = Path()
let g = WedgeGeometry(wedge, in: rect)
p.addArc(center: g.cen, radius: g.r0, startAngle: g.a0, endAngle: g.a1, clockwise: false) p.addLine(to: g.topRight)
p.addArc(center: g.cen, radius: g.r1, startAngle: g.a1, endAngle: g.a0, clockwise: true) p.closeSubpath()
return p
}
}
将自定义的形状用在自定义的View中
struct RingView: View {
@EnvironmentObject var ring: Ring
var body: some View {
ZStack {
ForEach(ring.wedgeIDs) { id in
WedgeView(self.ring.wedges[id]!).tapAction { withAnimation { self.ring.deleteWedge(id: id) } }
}
}.transition(scaleAndFade)
}
}
Accessibility
Accessibility API的特性:
- 可理解
- 可交互
- 可导航
设置Accessibility label、Accessiblity value和Accessibility trait
CalculatorButton(.multiply)
.accessibility(label: Text("Multiply"))
.accessibility(addTraits: selected ? .isSelected : [])
.accessibility(value: Text("\(value)"))
设置Accessibility action
ResultView()
.accessibility(label: Text("Result"))
.accessibility(value: Text("\(value)"))
.accessibilityAction(named: Text("Clear")) {
}
隐藏Accessiblity
VStack(alignment: .leading) {
Text(verbatim: String(format: "Red: %.0f", red)) .accessibility(visibility: .hidden)
Slider(value: $red, from: 0, through: 255.0)
}