如何从SwiftUI的官方教程代码解释VStack {..}?

时间:2019-10-28 08:26:07

标签: swift swiftui

在下面的代码中,我知道

  1. body是仅包含get部分的计算属性。
  2. 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()
        }
    }
}

3 个答案:

答案 0 :(得分:3)

如果查看VStack.init的文档,您会发现它接受的最后一个参数确实是闭包。这里的魔力是闭包标记有@ViewBuilder

@ViewBuilderfunction builder的一种。这个想法是,您传入一个包含一堆 expressions 的闭包,然后函数构建器会将这些表达式组合为一个值。这有点像返回一个数组,但使用的语法可能更好看。 (尽管它实际上不是数组。闭包的返回类型由函数生成器决定。)

在您的代码中,您将返回一个包含4个视图的“数组”。

  1. MapView
  2. CircleImage
  3. 另一个VStack
  4. 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