SwiftUI中的Geometry Reader是什么?

Sha*_*von 19 swift swiftui

我正在学习SwiftUI。我遇到了“ GeometryReader”。我想知道为什么以及何时使用它?

kon*_*iki 42

更新

Since I posted the answer, I have also written an article on how GeometryReader works. Check it out for a more detailed explanation: https://swiftui-lab.com/geometryreader-to-the-rescue/


GeometryReader is a view that gives you access to the size and position of your parent. For example:

struct MyView: View {
    var body: some View {
        GeometryReader { geometry in
           // Here goes your view content,
           // and you can use the geometry variable
           // which contains geometry.size of the parent
           // You also have function to get the bounds
           // of the parent: geometry.frame(in: .global)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

I usually combine it with .background() to obtain some other view's bounds. For example, The Text view is hard to predict how large it would be in advance. When I need that information, I use this trick:

First I have defined a view called 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

Then, to get the bounds of a Text view (or any other view):

struct MyView: View {
    @State private var rect: CGRect = CGRect()

    var body: some View {
        Text("some text").background(GeometryGetter($rect))

        // You can then use rect in other places of your view:
        Rectangle().frame(width: 100, height: rect.height)
    }
}
Run Code Online (Sandbox Code Playgroud)

For some use cases, I posted some answers to other questions that use GeometryReader. Check them out:

Move textfields to avoid being hidden by the keyboard: /sf/answers/3970488791/

如何在SwiftUI中查看另一个视图的大小:https ://stackoverflow.com/a/56661706/7786555

注意

在GeometryGetter中,我添加了DispatchQueue.main.async {}来设置矩形。在某些情况下,否则可能会导致运行时警告:在视图更新期间修改状态

  • 更新了答案以包含一些用例。 (2认同)