在SwiftUI中使用获取视图的宽度

时间:2019-08-20 15:56:38

标签: swift swiftui

我需要在SwiftUI中获取渲染视图的宽度,这显然不那么容易。

我的观察方式是,我需要一个函数来返回视图的尺寸,就像这样简单。

请帮助我。

var body: some View {

        VStack(alignment: .leading) {

               Text(timer.name)
                   .font(.largeTitle)
                   .fontWeight(.heavy)

               Text(timer.time)
                   .font(.largeTitle)
                   .fontWeight(.heavy)
                   .opacity(0.5)

        }
}

2 个答案:

答案 0 :(得分:12)

获取子视图的尺寸是任务的第一部分。扩大维度的价值是第二部分。 GeometryReader可获得父视图的暗淡效果,这可能不是您想要的。为了获得有关子视图的暗淡效果,我们可以在其子视图上调用一个具有实际大小的修饰符,例如.background().overlay()

struct GeometryGetterMod: ViewModifier {

    @Binding var rect: CGRect

    func body(content: Content) -> some View {
        print(content)
        return GeometryReader { (g) -> Color in // (g) -> Content in - is what it could be, but it doesn't work
            DispatchQueue.main.async { // to avoid warning
                self.rect = g.frame(in: .global)
            }
            return Color.clear // return content - doesn't work
        }
    }
}

struct ContentView: View {
    @State private var rect1: CGRect = CGRect()
    var body: some View {
        let t = HStack {
            // make two texts equal width, for example
            // this is not a good way to achieve this, just for demo
            Text("Long text").overlay(Color.clear.modifier(GeometryGetterMod(rect: $rect1)))
            // You can then use rect in other places of your view:

            Text("text").frame(width: rect1.width, height: rect1.height).background(Color.green)
            Text("text").background(Color.yellow)
        }
        print(rect1)
        return t
    }
}

答案 1 :(得分:4)

获取View尺寸的唯一方法是使用GeometryReader。读者将返回容器的尺寸。

什么是几何读取器?该文档说:

  

根据其自身大小和坐标空间定义其内容的容器视图。 Apple Doc

因此您可以通过执行以下操作获取尺寸:

struct ContentView: View {

   @State var frame: CGSize = .zero

    var body: some View {
        HStack {
            GeometryReader { (geometry) in
                self.makeView(geometry)
            }
        }

    }

    func makeView(_ geometry: GeometryProxy) -> some View {
        print(geometry.size.width, geometry.size.height)
        self.frame = geometry.size
        return Text("Test")
                .frame(width: geometry.size.width)
    }
}

打印尺寸是HStack的尺寸,它是内部视图的容器。

您可能会使用另一个GeometryReader来获取内部尺寸。

但是请记住,SwiftUI是一个声明性框架。因此,您应该避免计算视图的尺寸:

阅读更多示例