ios - SwiftUI 如何在 HStack 中对齐 subview

标签 ios swift swiftui hstack

我对这个问题有类似的问题(还没有答案):SwiftUI HStack with GeometryReader and paddings
不同的是,我的目标是在 HStack 内对齐两个 View ,其中左 View 获得可用宽度的 1/3,右 View 获得可用宽度的 2/3。
使用 GeometryReader ChildView 内部弄乱了整个布局,因为它填满了高度。
这是我的示例代码:

struct ContentView: View {
    var body: some View {
        VStack {
            VStack(spacing: 5) {
                ChildView().background(Color.yellow.opacity(0.4))
                ChildView().background(Color.yellow.opacity(0.4))
                Spacer()
            }

            .padding()

            Spacer()

            Text("Some random Text")
        }
    }
}

struct ChildView: View {
    var body: some View {
        GeometryReader { geo in
            HStack {
                Text("Left")
                    .frame(width: geo.size.width * (1/3))
                Text("Right")
                    .frame(width: geo.size.width * (2/3))
                    .background(Color.red.opacity(0.4))
            }
            .frame(minWidth: 0, maxWidth: .infinity)
            .background(Color.green.opacity(0.4))
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
结果如下:
enter image description here
现在,如果您将此 View 嵌入其他 View 中,则布局完全困惑:
例如里面ScrollView enter image description here
那么如何实现拥有 HStack 的预期结果? -ChildView 填充它获得的空间并将其划分(1/3、2/3)在它的两个 child 之间?
编辑
如答案中所述,我也忘记添加HStack(spacing: 0) .忽略这一点是右子容器溢出的原因。

最佳答案

您可以创建自定义 PreferenceKey对于 View 大小。 Here是一个例子:

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

    static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
        value = nextValue()
    }
}
然后,创建一个将计算其大小并将其分配给 ViewSizeKey 的 View 。 :
struct ViewGeometry: View {
    var body: some View {
        GeometryReader { geometry in
            Color.clear
                .preference(key: ViewSizeKey.self, value: geometry.size)
        }
    }
}
现在,您可以在 ChildView 中使用它们。 (即使它被包裹在 ScrollView 中):
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`
        }
                    
    }
}

关于ios - SwiftUI 如何在 HStack 中对齐 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66655570/

相关文章:

ios - 在 uitableviewcell 中切换复选框图像

ios - 选项卡式应用程序 - 如何隐藏选项卡栏

ios - 如何将 SwiftUI View 放置在 UIKit (UIViewRepresentable) View 之上? (错误或错误?)

ios - 无法将可选值解包到标签

ios - 为什么 viewDidLoad 被调用两次

iOS - UITableViewCell 中文本周围的圆角矩形,如 Things 应用程序

swift - 使用 Xcode 7 Beta 将 SpriteKit 项目升级到 Swift 2 后出错

ios - 将多个 Cocoapods 添加到一个 Xcode 项目

SwiftUI:拉伸(stretch)背景图像以填充

ios - SwiftUI View 不更新