What is Geometry Reader in SwiftUI?

后端 未结 2 504
小鲜肉
小鲜肉 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.

    0 讨论(0)
  • 2020-11-28 06:05

    What is called Reader in The SwiftUI?

    In addition to the kontiki's answer, Readers are container views that define their content as a function. So they can have some access and abilities about their parent. They are generic structs if you look more closely and there is 2 readers available now in SwiftUI 2.0:

    Note that it's just a convention, they're not conforming special protocl more of the View protocl.

    GeometryReader

    struct GeometryReader<Content: View> : View
    

    This is A container view that defines its content as a function of its own size and coordinate space. So you can detect frame and position changes and the current state of any view withing a GeometryReader. One of the popular usage of this reader that when you need separate views in separate stacks have the same (or relative) sizes.


    ScrollViewReader

    struct ScrollViewReader<Content: View> : View
    

    This is view whose child is defined as a function of a ScrollViewProxy targeting the scrollable views within the child. So you can have some access to the scrollview like scrolling to a specific item in a list or similar stuff.

    To minimalizing the duplication, I didn't post examples, you can check the link for more information if you want

    0 讨论(0)
提交回复
热议问题