Form 中的分隔符在 macOS 上不会一直延伸

问题描述 投票:0回答:1

我有这个 SwiftUI 表单:

var body: some View {
    Form {
        TextField("One label", text: $field1)
        Divider()
        TextField("Another label", text: $field2)
    }
}

在 macOS 上,分隔线不会一直延伸到整个表单,而是停在输入标签的右侧。怎样才能让它一直顺利呢?

这是一个屏幕截图来说明我正在尝试做的事情:

swift macos swiftui
1个回答
0
投票

使用 SwiftUI 获得准确的布局可能很困难。许多使用自动布局可以实现且(在我看来)相对简单的事情在 SwiftUI 中要做起来要困难得多。特别是,

Form
在 macOS 上几乎不允许自定义,如果您不喜欢它布置控件的方式,您通常最终不得不完全放弃
Form
并找到一种不同的方式来布置视图。

在这种情况下,您可以通过使用

Grid
而不是
Form
来获得屏幕截图的良好近似值,幸运的是,它甚至不需要像自定义
Layout
PreferenceKey
甚至
 这样的恶作剧GeometryReader
。这是我的结果:

这是代码:

import SwiftUI

struct GeneralTab: View {
    var body: some View {
        Grid(alignment: .leadingFirstTextBaseline) {
            GridRow {
                Text("Behavior:").gridColumnAlignment(.trailing)
                Picker("Behavior:", selection: .constant("Classic")) {
                    Text("Classic").tag("Classic")
                    Text("Something Else").tag("Something Else")
                }
                .fixedSize()
                .labelsHidden()
            }

            Text(
                """
                Classic behavior brings all of an app's windows to the front when one is clicked. Modern behavior brings only the clicked window to the front.

                To get the opposite of the chosen behavior, hold down the Shift key while clicking a window.
                """
            )
            .fixedSize(horizontal: false, vertical: true)
            .font(.callout)
            .foregroundStyle(.gray)

            Divider()

            GridRow {
                Text("Trigger:").gridColumnAlignment(.trailing)
                Picker("Trigger:", selection: .constant("Any Activation")) {
                    Text("Any Activation").tag("Any Activation")
                    Text("Something Else").tag("Something Else")
                }
                .fixedSize()
                .labelsHidden()
            }

            Text(
                """
                When set to Window Click, only app activations triggered by a click on a window will be considered. When set to Any Activation, all app activations will be considered.
                """
            )
            .fixedSize(horizontal: false, vertical: true)
            .font(.callout)
            .foregroundStyle(.gray)

            Divider()

            GridRow {
                Text("Interface:").gridColumnAlignment(.trailing)
                Toggle("Show Dock icon", isOn: .constant(false))
            }

            GridRow {
                Spacer().frame(width: 0, height: 0)
                Toggle("Show menu bar icon", isOn: .constant(true))
            }

            GridRow {
                Text("Startup:").gridColumnAlignment(.trailing)
                Toggle("Open automatically at login", isOn: .constant(true))
            }

            GridRow {
                Spacer().frame(width: 0, height: 0)
                Toggle("Hide on launch", isOn: .constant(false))
            }
        }
    }
}

struct ContentView: View {
    var body: some View {
        TabView {
            GeneralTab()
                .padding()
                .tabItem { Text("General") }
            Text("exclude")
                .padding()
                .tabItem { Text("Exclude") }
        }
        .overlay(alignment: .bottom) {
            HStack {
                Text("1.4.1")
                    .foregroundStyle(.gray)
                Spacer()
                HelpLink { }
            }
            .padding(8)
        }
        .padding(.top)
        .padding([.horizontal, .bottom], 20)
        .frame(width: 440)
    }
}

@main
struct testApp: App {
    var body: some Scene {
        Window("Front and Center", id: "f&s") {
            ContentView()
                .preferredColorScheme(.light)
        }
        .windowResizability(.contentSize)
    }
}

#Preview {
    struct PreviewView: View {
        var body: some View {
            ContentView()
        }
    }

    return PreviewView()
        .preferredColorScheme(.light)
}
© www.soinside.com 2019 - 2024. All rights reserved.