Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chart in ScrollView - Cannot initiate scroll from chart #30

Closed
mgauthier opened this issue Mar 15, 2021 · 8 comments
Closed

Chart in ScrollView - Cannot initiate scroll from chart #30

mgauthier opened this issue Mar 15, 2021 · 8 comments

Comments

@mgauthier
Copy link

When I add a line chart with the touchoverlay enabled into a scrollview, I find that I can only scroll when I start the scroll gesture outside of the chart. Is this expected behavior?

@willdale
Copy link
Owner

That is as I would expect, I can't think of a way to differentiate between the two touch instructions.

@willdale
Copy link
Owner

The only implementation I can get to work is a Button in the ScrollView that turns on the DragGesture in .touchOverlay.

It's not the prettiest way of doing it but it would somewhat allow for what you want.

Screen.Recording.2021-03-16.at.10.44.45-Up.to.4K.mov

Let me know if you want this implemented or if you can think of a different way of doing it.

@mgauthier
Copy link
Author

Interesting, I'm curious to see the video, but I'm having trouble playing it

@willdale
Copy link
Owner

No idea why you can't play it but here's a link to a YouTube version

@willdale
Copy link
Owner

Feel free to come back to this.

@krin-san
Copy link

krin-san commented Jun 8, 2021

Could this be a better solution?

-                                DragGesture(minimumDistance: 0)
+                                DragGesture(minimumDistance: minDistance, coordinateSpace: .local)

minimumDistance set to 15 guarantees that vertical ScrollView can handle the gesture before ChartView does. With value of 10 InfoBox sometimes appears and stays always visible at the same time ScrollView handles the gesture.

Full patch

diff --git a/Sources/SwiftUICharts/Shared/ViewModifiers/TouchOverlay.swift b/Sources/SwiftUICharts/Shared/ViewModifiers/TouchOverlay.swift
index 8b4670dfc00d148e6f8301e9cf777f42dd269f06..33907751fb58a4005806dd6ed484bd5b784537f9 100644
--- a/Sources/SwiftUICharts/Shared/ViewModifiers/TouchOverlay.swift
+++ b/Sources/SwiftUICharts/Shared/ViewModifiers/TouchOverlay.swift
@@ -14,13 +14,16 @@ import SwiftUI
 internal struct TouchOverlay<T>: ViewModifier where T: CTChartData {
     
     @ObservedObject private var chartData: T
+    let minDistance: CGFloat
     
     internal init(
         chartData: T,
         specifier: String,
-        unit: TouchUnit
+        unit: TouchUnit,
+        minDistance: CGFloat
     ) {
         self.chartData = chartData
+        self.minDistance = minDistance
         self.chartData.infoView.touchSpecifier = specifier
         self.chartData.infoView.touchUnit = unit
     }
@@ -32,7 +35,7 @@ internal struct TouchOverlay<T>: ViewModifier where T: CTChartData {
                     ZStack {
                         content
                             .gesture(
-                                DragGesture(minimumDistance: 0)
+                                DragGesture(minimumDistance: minDistance, coordinateSpace: .local)
                                     .onChanged { (value) in
                                         chartData.setTouchInteraction(touchLocation: value.location,
                                                                       chartSize: geo.frame(in: .local))
@@ -83,11 +86,13 @@ extension View {
     public func touchOverlay<T: CTChartData>(
         chartData: T,
         specifier: String = "%.0f",
-        unit: TouchUnit = .none
+        unit: TouchUnit = .none,
+        minDistance: CGFloat = 0
     ) -> some View {
         self.modifier(TouchOverlay(chartData: chartData,
                                    specifier: specifier,
-                                   unit: unit))
+                                   unit: unit,
+                                   minDistance: minDistance))
     }
     #elseif os(tvOS)
     /**
@@ -99,7 +104,8 @@ extension View {
     public func touchOverlay<T: CTChartData>(
         chartData: T,
         specifier: String = "%.0f",
-        unit: TouchUnit = .none
+        unit: TouchUnit = .none,
+        minDistance: CGFloat = 0
     ) -> some View {
         self.modifier(EmptyModifier())
     }

@willdale willdale reopened this Jun 9, 2021
@willdale
Copy link
Owner

@krin-san you are a star! Sorry it took a while to look at this. I'll add it to the next release.

@willdale
Copy link
Owner

willdale commented Jun 21, 2021

This is now possible in v2.8.

.touchOverlay(chartData: data, specifier: "%.0f", minDistance: 10)

Thanks,
Will

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants