Ios SwiftUI如何在HStack内对齐子视图

Ios SwiftUI如何在HStack内对齐子视图,ios,swift,swiftui,hstack,Ios,Swift,Swiftui,Hstack,我对这个问题有一个类似的问题(还没有答案): 不同的是,我的目标是在HStack内对齐两个视图,其中左视图获得可用宽度的1/3,右视图获得可用宽度的2/3 在ChildView中使用GeometryReader会弄乱整个布局,因为它会填充高度 这是我的示例代码: struct ContentView:View{ var body:一些观点{ VStack{ VStack(间距:5){ ChildView().背景(颜色.黄色.不透明度(0.4)) ChildView().背景(颜色.黄色.不透明

我对这个问题有一个类似的问题(还没有答案):

不同的是,我的目标是在HStack内对齐两个视图,其中左视图获得可用宽度的1/3,右视图获得可用宽度的2/3

在ChildView中使用
GeometryReader
会弄乱整个布局,因为它会填充高度

这是我的示例代码:

struct ContentView:View{
var body:一些观点{
VStack{
VStack(间距:5){
ChildView().背景(颜色.黄色.不透明度(0.4))
ChildView().背景(颜色.黄色.不透明度(0.4))
垫片()
}
.padding()
垫片()
文本(“一些随机文本”)
}
}
}
结构子视图:视图{
var body:一些观点{
GeometryReader{geo-in
HStack{
文本(“左”)
.框架(宽度:geo.size.width*(1/3))
文本(“右”)
.框架(宽度:geo.size.width*(2/3))
.背景(颜色.红色.不透明度(0.4))
}
.frame(最小宽度:0,最大宽度:无穷大)
.背景(颜色.绿色.不透明度(0.4))
}
}
}
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView()
}
}
其结果是:

现在,如果将此视图嵌入到其他视图中,则布局将完全混乱:

e、 g.在
滚动视图中

那么,一个人如何获得一个
HStack
-ChildView的理想结果,这个ChildView填充了它所获得的空间,并将它(1/3,2/3)划分到它的两个孩子之间呢

编辑


如回答中所述,我还忘记添加
HStack(间距:0)
。忽略此项是右子容器溢出的原因。

您可以为视图大小创建自定义的
首选项键。例如:

struct ViewSizeKey: PreferenceKey {
    static var defaultValue: CGSize = .zero

    static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
        value = nextValue()
    }
}
然后,创建一个视图,该视图将计算其大小并将其分配给
ViewSizeKey

struct ViewGeometry: View {
    var body: some View {
        GeometryReader { geometry in
            Color.clear
                .preference(key: ViewSizeKey.self, value: geometry.size)
        }
    }
}
现在,您可以在
子视图
中使用它们(即使它包装在
滚动视图
):


我可以在你的代码中看到你想要2个ChildView()和一个文本,我想你想要它们每个垂直取1/3?虽然ChildView()的水平间距为1/3和2/3。在
滚动视图
中,您希望
ChildView
元素有多高?它们失去了计算固有大小的能力,因为没有高度来约束它们。SwiftPunk:我想约束水平间距@jnpdx我希望ChildView/TextView的行为与以前一样,它们只需要所需的高度。谢谢您的回答。它实际上解决了这个问题。我希望有一个更简单的方法,但这仍然是工作!
struct ChildView: View {
    @State var viewSize: CGSize = .zero
    
    var body: some View {
        HStack(spacing: 0) { // no spacing between HStack items
            Text("Left")
                .frame(width: viewSize.width * (1 / 3))
            Text("Right")
                .frame(width: viewSize.width * (2 / 3))
                .background(Color.red.opacity(0.4))
        }
        .frame(minWidth: 0, maxWidth: .infinity)
        .background(Color.green.opacity(0.4))
        .background(ViewGeometry()) // calculate the view size
        .onPreferenceChange(ViewSizeKey.self) {
            viewSize = $0 // assign the size to `viewSize`
        }
                    
    }
}