【问题标题】:SwiftUI grid with column that fits content?带有适合内容的列的 SwiftUI 网格?
【发布时间】:2020-09-21 16:43:59
【问题描述】:

SwiftUI 可以实现这种布局吗?

我希望第一列包含标签的大小,所以在这种情况下,它会大到足以显示“更大的标签:”。然后将剩余的空间留给第二列。

这个布局非常简单,带有自动布局。

SwiftUI 2020 有 LazyVGrid,但我看到的设置列大小的唯一方法是使用硬编码数字。他们不明白多语言和用户可调整字体大小会导致什么问题吗?

【问题讨论】:

    标签: swiftui lazyvgrid swiftui-layout


    【解决方案1】:

    如果比较代码行数以在两个世界中以编程方式实现这一点并不那么复杂......

    无论如何,这是可能的。这是一个基于使用视图首选项功能的一些帮助修饰符的解决方案。不难。没有网格。

    使用 Xcode 12 / iOS 14 准备和测试演示。

    struct DemoView: View {
        @State private var width = CGFloat.zero
    
        var body: some View {
            VStack {
                HStack {
                    Text("Label1")
                        .alignedView(width: $width)
                    TextField("", text: .constant("")).border(Color.black)
                }
                HStack {
                    Text("Bigger Label")
                        .alignedView(width: $width)
                    TextField("", text: .constant("")).border(Color.black)
                }
            }
        }
    }
    

    和助手

    extension View {
        func alignedView(width: Binding<CGFloat>) -> some View {
            self.modifier(AlignedWidthView(width: width))
        }
    }
    
    struct AlignedWidthView: ViewModifier {
        @Binding var width: CGFloat
    
        func body(content: Content) -> some View {
            content
                .background(GeometryReader {
                    Color.clear
                        .preference(key: ViewWidthKey.self, value: $0.frame(in: .local).size.width)
                })
                .onPreferenceChange(ViewWidthKey.self) {
                    if $0 > self.width {
                        self.width = $0
                    }
                }
                .frame(minWidth: width, alignment: .trailing)
        }
    }
    

    【讨论】:

    • 谢谢,我会接受这个答案,但我很好奇……Apple 有没有记录或说过以这种方式使用首选项? (要有效地将几何约束向上 传递到视图层次结构?)当人们去年开始这样做时,我的印象是这是一种 hack,一种巧妙地滥用偏好来弥补缺失的功能。 (如果我没记错的话,它有时会在我的控制台中生成警告消息。)我认为 SwiftUI 2020 会解决这个问题,但是......我在 WWDC 视频中没有听到任何关于它的消息。你有吗?
    • @RobN 从我读过的内容来看,这似乎正是 SwiftUI“首选项”的用途。这只是一个令人困惑的名字。我认为它们是自上而下的环境值的自下而上对应物。
    • 这个答案让我对我需要的东西有所了解。左侧标签的大小正确,但我的右列也需要调整大小以适合其内容,而是根据标签的大小调整方式被截断。
    • @Uncommon 似乎它们是为向上传递 values 而设计的,是的,但我怀疑它们是为 constraints 而设计的,而 SwiftUI 非常缺少这些, 在我看来。例如,如果视图更改大小,则此答案不起作用,这很常见。 (例如,文本内容发生变化。)
    猜你喜欢
    • 2017-09-28
    • 2020-06-10
    • 2019-02-05
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多