SwiftUI Divider 未调整自身大小以适应父视图?

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

我有一个相当基本的 SwiftUI 视图继承关系,我试图在其中插入一个分隔符,但是分隔符将自身大小调整为一些模糊的值,并将父视图推出以满足它。层次结构中的所有其他视图都表现正确,并且父视图正在包装最大的子视图,如预期的那样。

我搜索了又搜索,但找不到任何关于这种行为的见解 - 所以我向你们好心的人询问一些想法。

查看代码:

Form {
    HStack(alignment: .top) {
        VStack(alignment: .trailing) {
            Picker("Paper Size:", selection: $viewModel.layoutParameters.paperSize) {
                ForEach(PrintSize.allCases, id: \.self) {
                    Text($0.description)
                }
            }
            .pickerStyle(.menu)
                    
            Picker(selection: $viewModel.layoutParameters.margin) {
                ForEach(Margin.allCases, id: \.self) {
                    Text($0.description)
                }
            } label: {
                Text("Margins:")
                    .padding(.leading, 15) // This is janky, find a better way to do it.
            }
            .pickerStyle(.menu)
        }
                
        Divider()
                
        Picker("Default Print Size:", selection: $viewModel.layoutParameters.printSize) {
            ForEach(PrintSize.allCases, id: \.self) {
                Text($0.description)
            }
        }
        .pickerStyle(.menu)
    }
}
.padding(8)

使用分隔线表现出的行为:

不带分隔线:

如果您能给我一种在不显式应用填充的情况下推动边距标签的方法,那就加分了。

ios swift macos swiftui divider
1个回答
0
投票

您描述的两个问题都可以通过使用覆盖来解决。

  1. A
    Divider
    是贪婪的,会扩展到使用所有可用空间,就像
    Spacer
    一样。要将其限制为
    HStack
    的高度,只需将其叠加在
    HStack
    上即可。默认情况下,叠加层将与
    HStack
    的中心对齐。这是完美的,因为两个
    Picker
    将具有相等的宽度,因此
    Divider
    将自动定位在它们之间的中间。但是,需要两个额外的步骤才能使其看起来正确:
  • Divider
    的方向通常由包含它的堆栈决定,或者默认为水平方向。由于您希望它是垂直的,因此需要将其嵌套在虚拟对象中
    HStack
  • 您可能想要增加
    spacing
    使用的
    HStack
    ,因为现在两个
    Picker
    之间只有一个空格。
  1. 如果您希望“边距”标签与“纸张尺寸”标签具有相同的宽度,则可以使用较长标签的隐藏版本来确定所需的占用空间。然后在叠加层中显示较短的标签。

这是示例的更新版本,应用了两项更改:

Form {
    HStack(alignment: .top, spacing: 20) { // <- spacing added
        VStack(alignment: .trailing) {
            Picker("Paper Size:", selection: $viewModel.layoutParameters.paperSize) {
                ForEach(PrintSize.allCases, id: \.self) {
                    Text($0.description)
                }
            }
            .pickerStyle(.menu)

            Picker(selection: $viewModel.layoutParameters.margin) {
                ForEach(Margin.allCases, id: \.self) {
                    Text($0.description)
                }
            } label: {
                Text("Paper Size:")
                    .hidden()
                    .overlay(alignment: .trailing) {
                        Text("Margins:")
                    }
//                    .padding(.leading, 15) // This is janky, find a better way to do it.
            }
            .pickerStyle(.menu)
        }

//        Divider()

        Picker("Default Print Size:", selection: $viewModel.layoutParameters.printSize) {
            ForEach(PrintSize.allCases, id: \.self) {
                Text($0.description)
            }
        }
        .pickerStyle(.menu)
    }
    .overlay {
        HStack {
            Divider()
        }
    }
}
.padding(8)

Screenshot

© www.soinside.com 2019 - 2024. All rights reserved.