I am learning SwiftUI. And I come across to "GeometryReader". And I want to know why and when to use it?
3 Answers
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 its 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.
-
2Updated the answer to include some use cases. – kontiki Jun 24 '19 at 04:40
-
1Since I posted the answer, I added a link to an article I have written about GeometryReader. It expands the answer further. Cheers. – kontiki Jul 01 '19 at 15:34
-
Can you help us here https://stackoverflow.com/questions/57243677/proportional-height-or-width-in-swiftui to understand why the GeometryReader in the accepted answer needs the layoutPriority modifier in order to get the result? Thx. – superpuccio Jul 29 '19 at 23:10
-
That geometry getter is very useful. Thank you for posting. – テッド Feb 27 '20 at 11:25
-
1Very useful way of using Geometry reader, but i think calling frame(in:) asynchronously isn't a good idea for dynamic content (view inside list for instance), this will lead to crash, a workaround would be to fetch the frame synchronously and then dispatch it asynchrounouly – Aleyam May 22 '20 at 17:01
-
@Aleyam, do you have some sample code and if so, are you willing to create it as an answer? Thank you. – iPadawan Aug 13 '20 at 20:25
-
I'm getting crashes on `self.rect = geometry.frame(in: .global)` when changing tabs. Apparently, removing the Async call makes it work again. – mcatach Aug 14 '20 at 05:05
-
This technique might end up in endless loop depending on how you use the `rect` value. It was discussed in the WWDC 22 session "Compose custom layouts with SwiftUI" at 18:20 mark https://developer.apple.com/videos/play/wwdc2022/10056/ – chunkyguy Nov 22 '22 at 13:59
What is called Reader
in SwiftUI?
In addition to the kontiki's answer, Reader
s 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 protocol 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 within 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

- 5,383
- 7
- 50
- 89

- 95,414
- 31
- 268
- 278
GeometryReader is thing that recognize geometry of parents view means when you create a view in the geometry you get size of your parent view.

- 61
- 1
- 9