如何在 macOS 上将表单元素与 SwiftUI 正确对齐?懒惰网格?

vma*_*let 8 macos swiftui

作为练习,我尝试在 macOS (Big Sur) 上复制 Safari 中的“高级”首选项窗格,如下所示(没有导航栏):

Safari 高级偏好设置的屏幕截图

在此输入图像描述

我想知道正确的方法是水平和垂直地正确对齐窗口中的所有元素。我已经使用 a 进行了第一次尝试LazyVGrid,它非常接近,但我有几个问题:

  1. LazyVGrid办法做到吗,或者有更好的办法吗?
  2. 有了足够的元素,我很快就超出了视图构造函数的 10 个限制。我不得不求助于超级笨拙的构建器函数,到处都结合了 aForEachAnyViews 。有什么更好的办法呢?
  3. 除了“辅助功能”部分之外,一切都排列得很好,其中“辅助功能”与第一个切换“切勿使用大于...的字体”并不完美。在 Safari 的情况下,它们完美地排列在一起。

这是代码:

struct PrefsAdvancedView: View {
    let emptyCell = AnyView(Color(NSColor.clear))

    @Binding var bool1: Bool
    @Binding var bool2: Bool

    @State private var selectedStrength = "9"
    let strengths = [ "9" ]
    @State private var selectedSheet = "None Selected"
    let sheets = [ "None Selected", "fake1" ]
    @State private var selectedEncoding = "Western (ISO Latin 1)"
    let encodings = [ "Western (ISO Latin 1)", "fake1" ]


    private let columns = [GridItem(.fixed(150), alignment: .trailing),
                           GridItem(.fixed(300), alignment: .leading)]

    func buildGrid(_ index: Int) -> AnyView {
        switch (index) {
        case 0:
            return AnyView(Text("Smart Search Field:"))
        case 1:
            return AnyView(Toggle("Show full website address", isOn: $bool1))
        case 2:
            return AnyView(
                VStack {
                    Text("Accessibility:")
                    Spacer()
                })
        case 3:
            return AnyView(
                VStack(alignment: .leading) {
                    HStack {
                        Toggle("Never use font sizes smaller than", isOn: $bool2)
                        Picker(selection: $selectedStrength, label: EmptyView()) {
                            ForEach(strengths, id: \.self) {
                                Text($0)
                            }
                        }
                        .frame(maxWidth: 50)
                        .disabled(!bool2)
                    }
                    Toggle("Press Tab to highlight each item on a webpage", isOn: $bool2)
                    Text("Option-Tab highlights each item")
                        .font(.caption)
                        .padding(.leading, 15)
                })
        case 4:
            return AnyView(Text("Reading List:"))
        case 5:
            return AnyView(Toggle("Save articles for offline reading automatically", isOn: $bool2))
        case 6:
            return AnyView(Text("Style sheet:"))
        case 7:
            return AnyView(Picker(selection: $selectedSheet, label: EmptyView()) {
                ForEach(sheets, id: \.self) {
                    Text($0)
                }
            }
            .labelsHidden()
            )
        case 8:
            return AnyView(Text("Default encoding:"))
        case 9:
            return AnyView(Picker(selection: $selectedEncoding, label: EmptyView()) {
                ForEach(encodings, id: \.self) {
                    Text($0)
                }
            }
            .labelsHidden()
            )
        case 10:
            return AnyView(Text("Proxies:"))
        case 11:
            return AnyView(Button("Change Settings...", action: { }))
        //14: Empty
        case 13:
            return AnyView(Toggle("Show Develop menu in menu bar", isOn: $bool1))

        default:
            return emptyCell
        }
    }

    var body: some View {
        Form {
            LazyVGrid(columns: columns, spacing: 20) {
                ForEach(0..<14) { index in // Kudlgy. What's the right way?
                    buildGrid(index)
                }
            }
        }
        .padding()
    }
}
Run Code Online (Sandbox Code Playgroud)

这是运行时的样子:

基于 SwiftUI 的首选项窗格的屏幕截图

在此输入图像描述