SwiftUI之ViewBuilder
所属分类:ios | 发布于 2023-01-28
ViewBuilder就是一个包含多个视图的闭包。在SwiftUI框架中,所有的容器视图都使用@ViewBuilder来修饰最后一个参数,因为这些被@ViewBuilder修饰的视图容器可以接收多个子视图作为参数。
ViewBuilder的介绍
1、ViewBuilder的描述
A custom parameter attribute that constructs views from closures.
翻译一下:从闭包构造视图的自定义参数属性。
2、ViewBuilder的定义
@resultBuilder struct ViewBuilder
ViewBuilder本质上是一个结构体,并且被@resultBuilder注解,也就是说ViewBuilder是一个result builder(结果建造者)类型。
3、ViewBuilder的理解
使用@resultBuilder注解ViewBuilder结构体之后,就可以用@ViewBuilder来修饰闭包,这个闭包可以接收多个指定类型的对象,而这些对象会按照buildBlock函数的实现进行组织。
ViewBuilder结构体有11个名为buildBlock的函数,分别接收从0到10个View类型的参数,因此在SwiftUI中一个接收@ViewBuilder类型参数的视图容器最多能接收10个子视图,如果不能满足需求可以通过拆分来增加子视图的个数。
4、官方示例
通常使用ViewBuilder作为生成闭包参数的子视图的参数属性,允许这些闭包提供多个子视图。例如,以下contextMenu函数接受通过视图生成器生成一个或多个视图的闭包。
4.1、看看contextMenu函数的定义
extension View {
public func contextMenu<MenuItems>(
@ViewBuilder menuItems: () -> MenuItems
) -> some View where MenuItems : View
}
4.2、使用contextMenu的闭包构建视图
myView.contextMenu {
Text("Cut")
Text("Copy")
Text("Paste")
if isSymbol {
Text("Jump to Definition")
}
}
ViewBuilder的实践
1、自定义容器视图展示@ViewBuilder的用法
1.1、定义一个自定义容器视图
/// - 定义一个自定义容器视图
struct CustomViewBuilderContainerView<Content> : View where Content: View {
private let content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
VStack {
content
.padding()
}
.foregroundColor(.red)
.background(Color.green)
.font(.title)
}
}
1.2、使用自定义容器视图
/// - 自定义容器视图的使用
struct TestViewBuilderView: View {
var body: some View {
CustomViewBuilderContainerView {
Text("Hello, Swift!")
Text("Hello, SwiftUI!")
}
}
}