Touch Event on LEGENDS in Coreplot iOS

一世执手 提交于 2019-12-11 03:35:39

问题


I want that if the user touches a particular legend then i can trigger some action,say show details for that slice/bar/plot. Is there any delegate method for this besides :

-(NSString *)legendTitleForPieChart:(CPTPieChart *)pieChart recordIndex:(NSUInteger)index

Thanks!


回答1:


This is not available in coreplot as of now. You have to subclass CPTLegend class to add this functionality. There is already a request for this here.

Just to point you to right direction. In order to achieve this, you need to do the following,

  1. Modify the method renderAsVectorInContext to store the CGRect in which legend title and swatch is drawn. There should be a connection between the frame corresponding to the legend title.
  2. Modify the method -(BOOL)pointingDeviceDownEvent:(CPTNativeEvent *)event atPoint:(CGPoint)interactionPoint and check if the tap is on any of these CGRect stored above. If the point is within that frame you need to call a delegate method and tell which Legend was tapped. Check for similar implementation of this method in other coreplot classes. It should be almost similar in this case to identify whether the point of tap lies within this frame or not.



回答2:


I implemented It in my coreplot subclass. Here are the things I did (probably isn't the best method, but I got things working here):

1-Create a category for CPlot, and add a property called CGRect legendRect;

2-While initializing the plots, set this property as CGRectZero for each plot;

3-Add the protocol CPTLegendDelegate and implement the method below:

-(BOOL)legend:(CPTLegend *)legend shouldDrawSwatchAtIndex:(NSUInteger)idx forPlot:(CPTPlot *)plot inRect:(CGRect)rect inContext:(CGContextRef)context
{
    if (CGRectEqualToRect(plot.legendRect, CGRectZero)) {
        plot.legendRect = CGRectUnion(self.graph.legend.frame, rect);
    }
    return !plot.hidden;
}

3-Add the protocol CPTPlotSpaceDelegate and implement the method below:

-(BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceDownEvent:(UIEvent *)event atPoint:(CGPoint)point
{
    if (CGRectContainsPoint(self.graph.legend.frame, point)) {

       CGPoint pointInLegend = CGPointMake(point.x - self.graph.legend.frame.origin.x, point.y - self.graph.legend.frame.origin.y);

        [self.graph.allPlots enumerateObjectsUsingBlock:^(CPTPlot *plot, NSUInteger idx, BOOL *stop) {
            if (CGRectContainsPoint(plot.legendRect, pointInLegend))
            {
                //here you can do whatever you need
                plot.hidden = !plot.hidden;
                [self configureLegend]; 
                *stop = YES;
            }
        }];
    }
    return YES;
}

When user touch the legend item (swatch or label), the toched plot will be hidden. Probably this could be implemented inside coreplot.

Regards, Almir



来源:https://stackoverflow.com/questions/13525803/touch-event-on-legends-in-coreplot-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!