SwiftUI:在带间隔器的 VStack 中平均分配多个 VStack

SwiftUI: Distribute equally multiple VStacks in a VStack with Spacers

我正在尝试构建一个包含多个 VStack(元素)的 VStack(容器),每个 VStack 都有一个标题和一个文本。元素VStacks应该均匀分布,中间有间隔。

出于某种原因,它最多只能使用 4 个元素的 VStack,如果我增加,则会出现错误

Failed to build ContentView.swift
Ambiguous reference to member 'buildingBlock()'

这是我的代码:

import SwiftUI

struct ContentView: View {
    var body: some View {

        VStack {
            Spacer()
            VStack {
                Text("Title 1")
                Text("Text 1")
            }
            Spacer()
            VStack {
                Text("Title 2")
                Text("Text 2")
            }
            Spacer()
            VStack {
                Text("Title 3")
                Text("Text 3")
            }
            Spacer()
            VStack {
                Text("Title 4")
                Text("Text 4")
            }
            Spacer()
            VStack {
                Text("Title 5")
                Text("Text 5")
            }
            Spacer()
            VStack {
                Text("Title 6")
                Text("Text 6")
            }
            Spacer()
            VStack {
                Text("Title 7")
                Text("Text 7")
            }
            Spacer()
            VStack {
                Text("Title 8")
                Text("Text 8")
            }
            Spacer()
            VStack {
                Text("Title 9")
                Text("Text 9")
            }
            Spacer()
            VStack {
                Text("Title 10")
                Text("Text 10")
            }
            Spacer()'
        }
        .background(Color.red)

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

由于 SwiftUI 的实现方式,一个视图最多只能有 10 个直接的显式子视图。您的 top-level VStack 有 21 个直接子视图:10 个 child VStack 和它们周围的 11 个 Spacer

有多种解决方法。如果你真的需要一个 hard-coded 子视图列表,你可以使用 Group 使一些 children 间接:

struct ContentView: View {
    var body: some View {

        VStack {
            Group {
                Spacer()
                VStack {
                    Text("Title 1")
                    Text("Text 1")
                }
                Spacer()
                VStack {
                    Text("Title 2")
                    Text("Text 2")
                }
                Spacer()
                VStack {
                    Text("Title 3")
                    Text("Text 3")
                }
            }
            Group {
                Spacer()
                VStack {
                    Text("Title 4")
                    Text("Text 4")
                }
                Spacer()
                VStack {
                    Text("Title 5")
                    Text("Text 5")
                }
                Spacer()
                VStack {
                    Text("Title 6")
                    Text("Text 6")
                }
            }
            Group {
                Spacer()
                VStack {
                    Text("Title 7")
                    Text("Text 7")
                }
                Spacer()
                VStack {
                    Text("Title 8")
                    Text("Text 8")
                }
                Spacer()
                VStack {
                    Text("Title 9")
                    Text("Text 9")
                }
            }
            Spacer()
            VStack {
                Text("Title 10")
                Text("Text 10")
            }
            Spacer()
        }
        .background(Color.red)
    }
}

这里,top-levelVStack有6个直children:3个Group,2个Spacer,1个VStack。每个Group还有6个直children:3VStack和3Spacer。没有视图超过 10 个直接 children.

此处更好的方法是使用 ForEach 生成 children:

struct ContentView: View {
    var body: some View {

        VStack {
            Spacer()
            ForEach(1 ... 10, id: \.self) { i in
                Group {
                    VStack {
                        Text("Title \(i)")
                        Text("Text \(i)")
                    }
                    Spacer()
                }
            }
        }
        .background(Color.red)
    }
}

现在 top-level VStack 只有两个直接子视图:第一个 SpacerForEachForEach 根据需要多次复制其子视图(Group)。

我们在这种情况下使用 Group 来允许 Swift 推断 ForEach 主体的类型,因为 ForEach 主体将包含两个语句( VStackSpacer) 会阻止 Swift 推断其类型。