【问题标题】:SwiftUI: Aligning views to the leading & trailing edges of another view in a VStackSwiftUI:将视图与 VStack 中另一个视图的前缘和后缘对齐
【发布时间】:2019-12-27 07:30:18
【问题描述】:

如何在 SwiftUI VStack 中将内容与另一个视图的前缘和后缘对齐?

我目前有以下 SwiftUI 代码:

struct MyBlock: View {
    var body: some View {
        Rectangle().foregroundColor(.gray).frame(width: 80, height: 80)
    }
}

struct MyGridView: View {
    var body: some View {
        HStack(spacing: 16) {
            MyBlock()
            MyBlock()
            MyBlock()
        }                       
    }
}

struct PinPad: View {
    var body: some View {
        VStack {
            MyGridView()
            HStack {
                Button(action: {}, label: { Text("Left Align") })
                Spacer()
                Button(action: {}, label: { Text("Right Align") })
            }
        }
    }
}

结果呈现如下:

但我真正想要的是"Left Align" ButtonMyGridView 的左/前缘对齐,"Right Align" ButtonMyGridView 的右/后缘对齐.

例如,像这样:

我显然在这里遗漏了一些非常基本的东西,因为在 UIKit 中使用自动布局是微不足道的。

【问题讨论】:

    标签: ios layout alignment swiftui


    【解决方案1】:

    解决布局问题需要做的第一件事是在视图上添加边框。这将使您看到视图的真实(和不可见)界限。问题会更清楚:

    在您的情况下,可以通过将其全部包装在 HStack 中并添加一些垫片来轻松修复:

    struct PinPad: View {
        var body: some View {
            HStack {
                Spacer()
                VStack {
                    MyGridView().border(Color.blue, width: 3)
                    HStack {
                        Button(action: {}, label: { Text("Left Align") }).border(Color.red, width: 3)
                        Spacer()
                        Button(action: {}, label: { Text("Right Align") }).border(Color.red, width: 3)
                    }
                }.border(Color.green, width: 3)
                Spacer()
            }
        }
    }
    

    【讨论】:

    • 这当然有效。除非有人能想出一个更优雅的解决方案,否则我现在就试一试。
    【解决方案2】:

    GeometryReader 是一个视图,可让您访问父母的大小和位置

    定义了一个名为 GeometryGetter 的视图,

    struct GeometryGetter: View {
    
        @Binding var rect: CGRect
    
        var body: some View {
            return GeometryReader { geometry in
                self.makeView(geometry: geometry)
            }
        }
    
        func makeView(geometry: GeometryProxy) -> some View {
            DispatchQueue.main.async {
                self.rect = geometry.frame(in: .global)
            }
    
            return Rectangle().fill(Color.clear)
        }
    }
    

    然后将代码更改如下,

    struct PinPad: View {
    
        @State private var rect: CGRect = CGRect()
    
        var body: some View {
            HStack {
                VStack {
                    MyGridView().background(GeometryGetter(rect: $rect))
                    HStack {
                        Button(action: {}, label: { Text("Left Align") })
                        Spacer()
                        Button(action: {}, label: { Text("Right Align") })
                    }.frame(width: rect.width)
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以在 VStack 之后添加 .fixedSize()。

      【讨论】:

        【解决方案4】:

        .fixedSize() 添加到您的 VStack 可以解决问题。

        struct PinPad: View {
            var body: some View {
                VStack {
                    MyGridView()
                    HStack {
                        Button(action: {}, label: { Text("Left Align") })
                        Spacer()
                        Button(action: {}, label: { Text("Right Align") })
                    }
                }
                .fixedSize()
            }
        }
        

        简要说明:

        关于自动布局的基本内容,在 swiftui 中取决于框架 我们使用的不同堆栈堆栈。在这个查询中,第一个 VStack 是 父视图,它围绕它的 childView 作为它的框架 它是明确提供的。但是,由于按钮的 HStack 没有提供任何明确的宽度,但由于Spacer(); (这明确地使按钮拖动到它们的边缘),HStack 的 框架具有可用屏幕大小的宽度,这使得父级 VStack 视图也随之放大。因此,我们需要 还要注意子视图框架以及父视图 查看。

        额外信息:-alignment: 添加到堆栈本身只会对齐该视图中的内容,而添加.frame(alignment:) 修饰符将对齐视图本身。

        【讨论】:

          猜你喜欢
          • 2020-06-03
          • 2021-09-29
          • 2021-06-28
          • 2022-01-16
          • 1970-01-01
          • 2021-11-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多