扬庆の博客

SwiftUI-可选或基于条件修饰符

字数统计: 802阅读时长: 3 min
2024/11/05 Share

应用程序中,有时需要添加可选或基于条件修饰符modifier
例如,如果想根据选择产生不同的效果,就不能使用三元运算符来设置.symbol 效果值。这种
情况下,有两种方案:要么编写这样的东西, 要么为此Image 创建新的视图,并在这里使用
该视图。

思考🤔:如果我们可以创建一个自定义修饰符,允许我们根据条件添加修饰符呢?

枚举 Effect

1
2
3
4
5
6
enum Effect: String, CaseIterable {
case bounce = "Bounce"
case breathe = "Breathe"
case pulse = "Pulse"
case rotate = "Rotate"
}

使用这个枚举根据不同数值展示不同样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
struct ContentView: View {
@State private var effect: Effect = .bounce

var body: some View {
Group {
Picker("", selection: $effect) {
ForEach(Effect.allCases, id: \.rawValue) {
Text($0.rawValue)
.tag($0)
}
}
.pickerStyle(.segmented)
.padding(20)

Rectangle()
.modifiers { rectangle in
switch effect {
case .bounce: rectangle.fill(.red)
case .breathe: rectangle.fill(.green)
case .pulse: rectangle.fill(.blue)
case .rotate: rectangle.fill(.yellow)

}
}
.ignoresSafeArea()
}
}
}

⚠️注意: .modifiers 修饰符 modifier 就是这里想要呈现的效果。

1
2
3
4
5
6
7
extension View {
@ViewBuilder
func modifiers<Content: View>(@ViewBuilder content: @escaping (Self) -> Content) -> some View {
content(self)
}
}

相当于通过 Self 作为参数,传递出去, 这样每个 enum 都能使用 Self 做具体的事情。

1. extension View

这段代码是对 View 协议的扩展。在 SwiftUI 中,所有视图(例如 Text、Button 等)都遵循 View 协议,因此这个扩展方法可以被应用到所有的 SwiftUI 视图。

2. @ViewBuilder

@ViewBuilder 是一个 Swift 属性包装器,用于构建视图的组合体。它允许在闭包中返回多个视图,并自动把它们组合成一个 View。在这里,@ViewBuilder 是为了让 content 闭包在返回视图时可以支持多视图组合,便于使用。

3. 泛型和闭包

​ • Content: View:定义一个泛型参数 Content,限定为 View 类型。这意味着 modifiers 函数会返回一个视图(some View),该视图的内容是 Content。

​ • content: @escaping (Self) -> Content:这是一个闭包参数,接收一个视图(Self)并返回一个新的 Content 视图。

​ • @escaping 表示这个闭包会被异步执行或者延迟使用。

4. content(self)

content(self) 表示在闭包中调用 content,并把当前视图实例(即 self)传递进去。然后,这个闭包会返回一个经过修改的视图。

用途

这个方法的目的是允许你定义一些动态的视图修改器,而不直接在视图上调用修饰符链。例如,你可以传入一个闭包来对视图进行多种修改,封装成一组操作。

1
2
3
4
5
6
7
8
注意
只有在没有三元条件或三元条件无法满足要求的情况下(本例中的枚举类型条件下),才能使用此修改器,因为**使用三元运算符可以保留视图标识**。

例如,如果您想根据特定条件应用填充,请使用三元操作符:

.padding(condition ? 15 : 20)

如果您不能使用三元运算符或三元运算符不能满足您的要求(就像本视频中给出的示例一样),那么请使用此修改器!

swiftui-optionalmodifer

🔚

CATALOG