在下面的代码中,我知道
body
是仅包含get
部分的计算属性。return
省略了VStack
但是Vstack之后的{ .. }
是什么?这是初始化还是关闭?
{}里面是什么,我认为什么也没回报。
struct ContentView: View {
var body: some View {
VStack {
MapView()
.frame(height: 300)
CircleImage()
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
Spacer()
}
}
}
答案 0 :(得分:3)
如果查看VStack.init
的文档,您会发现它接受的最后一个参数确实是闭包。这里的魔力是闭包标记有@ViewBuilder
。
@ViewBuilder
是function builder的一种。这个想法是,您传入一个包含一堆 expressions 的闭包,然后函数构建器会将这些表达式组合为一个值。这有点像返回一个数组,但使用的语法可能更好看。 (尽管它实际上不是数组。闭包的返回类型由函数生成器决定。)
在您的代码中,您将返回一个包含4个视图的“数组”。
MapView
CircleImage
VStack
Spacer
这些将传递给ViewBuilder
,并将它们全部合并为一个View
对象。
如果您想知道在每个视图末尾调用的方法在做什么,它们只是返回对其被调用对象进行微小修改的方法。例如,padding
返回相同的视图,但应用了一些填充。
答案 1 :(得分:2)
当您查看VStack
初始化程序的签名时:
public init(alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content)
您可以看到它带有3个参数,前两个参数具有默认值,因此可以省略(如您的示例)。最后一个是ViewBuilder
,没有默认值,因此需要提供。
当您查看ViewBuilder
的定义时,它需要0到10个视图:
static func buildBlock() -> EmptyView
static func buildBlock<Content>(Content) -> Content
static func buildBlock<C0, C1>(C0, C1) -> TupleView<(C0, C1)>
static func buildBlock<C0, C1, C2>(C0, C1, C2) -> TupleView<(C0, C1, C2)>
/....
static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)>
长话短说,在{..}之间看到的是一个ViewBuilder
,它是一个闭包,是初始化程序的一部分。
答案 2 :(得分:1)
由于Swift 5.1中有一个名为 Function Builder 的新功能,因此$table = $section->addTable();
$table->addRow();
$cell = $table->addCell(11000);
$textrun = $cell->addTextRun();
$textrun->addFormField('checkbox')->setValue('<w:sym w:font="Wingdings" w:char="F0FE"/>');
$textrun->addText(htmlspecialchars(' Checkbox 1 '));
语法成为可能。
没有函数构建器,代码将如下所示:
VStack