具有适合内容的列的SwiftUI网格?

具有适合内容的列的SwiftUI网格?,swiftui,lazyvgrid,swiftui-layout,Swiftui,Lazyvgrid,Swiftui Layout,SwiftUI可以使用这种布局吗 我希望第一列包装标签的大小,因此在本例中,它将足够大,以显示“更大的标签:”。然后将剩余的空间分配给第二列 使用自动布局,此布局非常简单 Swiftui2020有LazyVGrid,但我看到的唯一设置列大小的方法是使用硬编码的数字。他们不明白多语言和用户可调字体大小会导致什么问题吗?如果比较代码行的数量,以编程方式在两个世界中实现这一点并不复杂 无论如何,这当然是可能的。下面是一个基于使用视图首选项功能的帮助修改器的解决方案。不难。没有网格 使用Xcode 12

SwiftUI可以使用这种布局吗

我希望第一列包装标签的大小,因此在本例中,它将足够大,以显示“更大的标签:”。然后将剩余的空间分配给第二列

使用自动布局,此布局非常简单


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

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

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

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

和助手

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)
    }
}
扩展视图{
func alignedView(宽度:Binding)->一些视图{
修改器(对齐宽度视图(宽度:宽度))
}
}
结构对齐宽度视图:视图修改器{
@绑定变量宽度:CGFloat
func正文(内容:内容)->某些视图{
内容
.背景(GeometryReader{
颜色。清晰
.preference(键:ViewWidthKey.self,值:$0.frame(in:.local).size.width)
})
.onPreferenceChange(ViewWidthKey.self){
如果$0>self.width{
self.width=$0
}
}
.frame(最小宽度:宽度,对齐方式:。尾随)
}
}

谢谢,我会接受这个答案,但我很好奇。。。苹果有没有记录或说过这样使用偏好?(为了有效地在视图层次结构中传递几何约束?)去年人们开始这样做时,我的印象是这是一种黑客行为,一种巧妙地滥用偏好来弥补缺少的功能。(如果我没记错的话,它有时会在我的控制台中生成警告消息。)我以为Swiftui2020会解决这个问题,但是。。。我在WWDC的视频中没有听到任何关于它的消息。是吗?@RobN从我所读到的来看,这似乎正是SwiftUI“首选项”的目的。这只是一个令人困惑的名字。我认为它们是自下而上的,与自上而下的环境价值观相对应。这个答案让我在某种程度上满足了我的需要。左侧标签的大小正确,但我的右侧列也需要调整大小以适应其内容,相反,它会根据标签的大小被截断。@是的,它们似乎是为向上传递值而设计的,但我怀疑它们是为约束而设计的,在我看来,SwiftUI非常缺少约束。例如,如果视图更改了大小(这是常见的),则此答案不起作用。(例如,文本内容发生变化。)
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)
    }
}