I assume you would like to obtain the size value of a view and work with it later. This can be accomplished by utilizing Preferences.
1. Creating the PreferenceKey
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
2. Using the PreferenceKey
Implement the PreferenceKey
and make use of GeometryReader
on the desired View to extract its size.
.background {
GeometryReader { geometry in
Color.clear.preference(key: SizePreferenceKey.self,
value: geometry.size)
}
}
3. Retrieving the size value
.onPreferenceChange(SizePreferenceKey.self) { size in
print("size of the red text is: \(size)")
// use the value however you want
sizeOfText = size
}
The entire code then looks like this:
struct GeometryReaderTest: View {
@State private var sizeOfRedText: CGSize = .zero
var body: some View {
VStack {
Text("Green text")
.background { Color.green }
Text("Red text")
.background { Color.red }
// PreferenceKey & GeometryReader usage
.background {
GeometryReader { geometry in
Color.clear.preference(key: SizePreferenceKey.self,
value: geometry.size)
}
}
}
.onPreferenceChange(SizePreferenceKey.self) { size in
print("size of the red text is: \(size)")
// use the value however you want
sizeOfRedText = size
}
}
}
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
4. Extension
You can create an extension
to conveniently extract the size of different views within your project.
extension View {
func getSizeOfView(_ getSize: @escaping ((CGSize) -> Void)) -> some View {
return self
.background {
GeometryReader { geometry in
Color.clear.preference(key: SizePreferenceKey.self,
value: geometry.size)
.onPreferenceChange(SizePreferenceKey.self) { value in
getSize(value)
}
}
}
}
}
Then you can call the getSizeOfView
like this:
Text("Red text")
.background { Color.red }
.getSizeOfView { size in
print("size of the red text is: \(size)")
sizeOfRedText = size
}