Skip to content

Instantly share code, notes, and snippets.

@huynguyencong
Created April 10, 2024 05:35
Show Gist options
  • Save huynguyencong/2894dfed7d6be9cb4a196fc71f6aef3e to your computer and use it in GitHub Desktop.
Save huynguyencong/2894dfed7d6be9cb4a196fc71f6aef3e to your computer and use it in GitHub Desktop.
import SwiftUI
struct ReadPositionModifier<Key: PreferenceKey>: ViewModifier where Key.Value == CGRect {
let parentCoordinateSpaceName: String
func body(content: Content) -> some View {
content
.background {
GeometryReader { proxy in
Color.clear
.preference(key: Key.self, value: proxy.frame(in: .named(parentCoordinateSpaceName)))
}
}
}
}
extension View {
/// Read view position from a parent coordinate space.
///
/// Define a `PreferenceKey` which its value is a `CGRect`. In the parent view, call two methods below,
/// to determine the parent coordinate space, and receive value changes:
///
/// .coordinateSpace(name: parentCoordinateSpaceName)
/// .onPreferenceChange(CustomPreferenceKey.self, perform: onPositionChange)
///
/// - Parameter key: the PreferenceKey to receive value changes, which its value is a CGRect
/// - Parameter parentCoordinateSpaceName: name of parent coordinate space
func readPosition<Key: PreferenceKey>(
key: Key.Type,
in parentCoordinateSpaceName: String
) -> some View where Key.Value == CGRect {
self.modifier(ReadPositionModifier<Key>(parentCoordinateSpaceName: parentCoordinateSpaceName))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment