测量 SwiftUI 视图的渲染大小?

Sea*_*ker 6 swiftui

在 SwiftUI 运行其视图渲染阶段后,有没有办法测量视图的计算大小?例如,给定以下视图:

struct Foo : View {
    var body: some View {
        Text("Hello World!")
            .font(.title)
            .foregroundColor(.white)
            .padding()
            .background(Color.red)
    }
}
Run Code Online (Sandbox Code Playgroud)

选择视图后,计算出的大小显示在左下角的预览画布中。有谁知道在代码中访问该大小的方法?

在此处输入图片说明

Pau*_*l B 8

打印出值很好,但能够在父视图(或其他地方)中使用它们更好。所以我又采取了一步来详细说明它。

struct GeometryGetter: View {
    @Binding var rect: CGRect

    var body: some View {
        GeometryReader { (g) -> Path in
            print("width: \(g.size.width), height: \(g.size.height)")
            DispatchQueue.main.async { // avoids warning: 'Modifying state during view update.' Doesn't look very reliable, but works.
                self.rect = g.frame(in: .global)
            }
            return Path() // could be some other dummy view
        }
    }
}

struct ContentView: View {
    @State private var rect1: CGRect = CGRect()
    var body: some View {
        HStack {
            // make to texts equal width, for example
            // this is not a good way to achieve this, just for demo
            Text("Long text").background(Color.blue).background(GeometryGetter(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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `Color.clear` 可以作为一个非常好的虚拟视图,因为它会扩展以填充所有空间并且语法上看起来不错:) (2认同)

小智 6

您可以使用 GeometryReader 添加“叠加层”以查看值。但在实践中,使用“背景”修饰符并离散处理大小值可能会更好

struct Foo : View {
    var body: some View {
        Text("Hello World!")
            .font(.title)
            .foregroundColor(.white)
            .padding()
            .background(Color.red)
            .overlay(
                GeometryReader { proxy in
                    Text("\(proxy.size.width) x \(proxy.size.height)")
                }
            )
    }
}
Run Code Online (Sandbox Code Playgroud)


Rus*_*ian 2

这是我想出的实现这一目标的丑陋方法:

struct GeometryPrintingView: View {

    var body: some View {
        GeometryReader { geometry in
            return self.makeViewAndPrint(geometry: geometry)
        }
    }

    func makeViewAndPrint(geometry: GeometryProxy) -> Text {
        print(geometry.size)
        return Text("")
    }
}
Run Code Online (Sandbox Code Playgroud)

并更新Foo版本:

struct Foo : View {
    var body: some View {
        Text("Hello World!")
            .font(.title)
            .foregroundColor(.white)
            .padding()
            .background(Color.red)
            .overlay(GeometryPrintingView())
    }
}
Run Code Online (Sandbox Code Playgroud)