Drag Chart UIView


#1

Is there a way to drag the actual uiview of the chart itself? The only way I have been able to do this is to put a transparent uiview over the chart view and use gestures on that, but this makes the chart unselectable. I turned off chart scrolling but the charts uiview won’t move when I try to drag it. I am trying to put the charts in a scroll view like this one: http://www.cocoawithlove.com/2009/01/multiple-virtual-pages-in-uiscrollview.html


#2

I’m dealing with a similar issue. I have multiple charts inside custom UITableViewCells. I haven’t yet gotten a chance to work on it, but my plan is to intercept the gestures, and apply certain ones to the TableViewCell (vertical swipe) and pass through others (horizontal swipe / pan, pinch / zoom) to the chart itself. Let’s keep each other up to date on any progress. Most likely, I’ll be working on this within the next 2 weeks.


#3

Hi guys,

I responded to the support ticket that Justin raised regarding this, and I figured it would be worth posting on the forum as well.  :-)

It looks like the issue both of you are experiencing is due to the chart gesture recognizers swallowing gestures once they have handled them.  You can configure them not to do this, it just takes a bit of digging in the code base to find out how to do this.

The gesture recognizers on charts are added to the chart canvas overlay.  You can get to this property of a chart as follows:

chart.canvas.overlay

In order to work with the chart canvas, or its overlay, you need to import the header files for both classes.  This can be done as follows:

#import <ShinobiCharts/SChartCanvas.h>
#import <ShinobiCharts/SChartCanvasOverlay.h>

In order to get the gesture recognizers from the chart canvas overlay, we could do the following:

NSArray *gestureRecognizers = chart.canvas.overlay.gestureRecognizers;

The gestureRecognizers property is common to all UIViews.  Now that we have access to the gesture recognizers on the chart, we can stop them swallowing gestures.  To do this, I would update the class where you create the charts, and make it adopt the UIGestureRecognizerDelegate protocol.  Once you have done that, you can implement the gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: protocol method, like so: 

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

 This implementation means that any gesture recognizers which use this delegate will allow other gesture recognizers to handle the gesture as well.  Now we can go through the gesture recognizers on the chart canvas overlay, and set them to use the new delegate:

NSArray *gestureRecognizers = chart.canvas.overlay.gestureRecognizers;
for (UIGestureRecognizer *gestureRecognizer in gestureRecognizers) {
    gestureRecognizer.delegate = self; // In this example, I created the charts in a view controller, and set the same view controller to be the delegate
}

This approach should allow you to put charts inside things like table views or scroll views without losing the normal scrolling behavior in the parent.

Hope this helps!


#4

Great post.  

I’m working with a slide out menu that opens if a user swipes horizontally anywhere in the view controller.  The above code works great to ignore horizontal swipes inside of chart view only if I return NO in the UIGestureRecognizerDelegate method.  I am seeing an issue though with respects to the default crosshair/tooltip.  If i press to hold and activate the crosshair and then drag to the right the gesture is being passed through and opening up the sliding menu.  Is there a way to fix this as well?

Thanks.


#5

Hey Brandoneggar!

For the crosshair we use a UILongPressGestureRecognizer - in your loop over the canvas overlay’s gesture recognisers, you could do a class check (isKindOfClass), and if it’s the UILongPressGestureRecognizer, don’t set its delegate. That way the long press gesture will always go to the chart.

Hope this helps!

Rob