I am trying to read location in DragGesture of a View connected to a ScrollView, but ScrollView take control of DragGesture on all view and does not let me to read those information. Here is my example to show the issue, My Goal is reading the Drag location in DragGesture.
using new code:
struct ContentView: View {
@State var locationY: CGFloat = .zero
var body: some View {
VStack {
HStack {
VStack {
Color.black.frame(height: 300)
}
.gesture( DragGesture().onChanged { value in locationY = value.location.y; print(locationY)} )
ScrollView {
VStack {
Color.blue.frame(height: 300)
}.background(GeometryReader {
Color.clear.preference(key: ViewOffsetKey.self,
value: $0.frame(in: .global).origin.y)
// value: $0.frame(in: .named("scroll_area")).origin.y)
})
}
// .coordinateSpace(name: "scroll_area")
.onPreferenceChange(ViewOffsetKey.self) {
self.locationY = $0
print(">> offset: \($0)")
}
.frame(height: 300)
}
Spacer()
}
}
}
struct ViewOffsetKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue = CGFloat.zero
static func reduce(value: inout Value, nextValue: () -> Value) {
value += nextValue()
}
}
Here is possible solution, to use GeometryReader
in background to read rect of view (in any needed coordinate space) and view preferences to pass needed coordinate at top level.
Tested with Xcode 12.1 / iOS 14.1
Note: commented variant is for superview (ie. ScrollView) coordinates
ScrollView
{
VStack
{
Color.blue.frame(height: 300)
}.background(GeometryReader {
Color.clear.preference(key: ViewOffsetKey.self,
value: $0.frame(in: .global).origin.y)
// value: $0.frame(in: .named("scroll_area")).origin.y)
})
}
// .coordinateSpace(name: "scroll_area")
.onPreferenceChange(ViewOffsetKey.self) {
self.locationY = $0
print(">> offset: \($0)")
}
and helper preference key
struct ViewOffsetKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue = CGFloat.zero
static func reduce(value: inout Value, nextValue: () -> Value) {
value += nextValue()
}
}