What is Geometry Reader in SwiftUI?

后端 未结 2 548
小鲜肉
小鲜肉 2020-11-28 05:41

I am learning SwiftUI. And I come across to \"GeometryReader\". And I want to know why and when to use it?

2条回答
  •  心在旅途
    2020-11-28 06:03

    UPDATE

    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 it's 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)
            }
        }
    }
    

    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)
        }
    }
    

    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)
        }
    }
    

    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: https://stackoverflow.com/a/56721268/7786555

    How to make view the size of another view in SwiftUI: https://stackoverflow.com/a/56661706/7786555

    Note

    In GeometryGetter, I added a DispatchQueue.main.async {} to set the rect. In some cases it could lead to runtime warning otherwise: Modifying state during view update.

提交回复
热议问题