iPhone Multi touch interactive to CorePlot

后端 未结 2 2002
遇见更好的自我
遇见更好的自我 2021-02-08 09:42

I\'m developing an iPhone application with core-plot chart. With the help of some tutorials, i managed to do it with single touch and drag. How can I make it with multiple touch

2条回答
  •  北海茫月
    2021-02-08 09:55

    I came across the same problem recently and couldn't find any solution. After some time researching and coding I found some solutions and want to share one, quite easy one, so it may help you get an idea how to approach this.

    I have created transparent UIView, which I've put on top of CPTGraphHostingView. This view was handling needed touch events. Let's name it TestView

    TestView.h file looks like

    @protocol TestViewDelegate 
    - (void)myTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
    - (void)myTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
    - (void)myTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
    
    @end
    
    @interface TestView : UIView
    @property (nonatomic, weak) id delegate;
    @end
    

    TestView.m

    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            // Initialization code
        }
        return self;
    }
    
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
        [self.delegate myTouchesBegan:touches withEvent:event];
    }
    
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
        [self.delegate myTouchesMoved:touches withEvent:event];
    }
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
        [self.delegate myTouchesEnded:touches withEvent:event];
    }
    

    TestView delegate, in my case viewController, which includes corePlot hosting view, will implement those methods and see the sample of the code below

    - (void)myTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
        if (touches.count == 1) {
            UITouch *touch = (UITouch *)[[touches allObjects] objectAtIndex:0];
            CGPoint point = [touch locationInView:nil];
            [self plotSpace:self.plotSpace shouldHandlePointingDeviceDraggedEvent:event atPoint:point];
        }
        if (touches.count == 2) {
            UITouch *touch = (UITouch *)[[touches allObjects] objectAtIndex:1];
            CGPoint point = [touch locationInView:nil];
            [self plotSpace:self.plotSpace shouldHandlePointingDeviceDraggedEvent:event atPoint:point];
        }
    }
    

    CPTPlotSpace delegate method in viewController will look like

    - (BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceDraggedEvent:(id)event atPoint:(CGPoint)point{
        NSSet *allTouches = [event allTouches];
        if ([allTouches count] >0 ) {
            UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];
            if (touch1){
                CGPoint pointInPlotArea = [self.graph convertPoint:[touch1 locationInView:self.view] toLayer:self.graph.plotAreaFrame];
    //              padding
                pointInPlotArea.x -=10;
                NSDecimal newPoint[2];
                [self.graph.defaultPlotSpace plotPoint:newPoint forPlotAreaViewPoint:pointInPlotArea];
                NSDecimalRound(&newPoint[0], &newPoint[0], 0, NSRoundPlain);
                int x = [[NSDecimalNumber decimalNumberWithDecimal:newPoint[0]] intValue];
                x--;
    
                if (x <= 0)
                    x = 0;
                else if (x >= [self.currentDatapoints count])
                    x = [self.currentDatapoints count] - 1;
    
                selectedCoordination = x;
                self.label.text = [NSString stringWithFormat:@"%@", [self.currentDatapoints objectAtIndex:x]];
                self.differenceLabel.text = @"";
                [touchPlot reloadData];
            }
            if ([allTouches count] > 1){
                secondTouchPlot.hidden = NO;
                UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];
                if (touch2) {
                    CGPoint pointInPlotArea = [self.graph convertPoint:[touch2 locationInView:self.view] toLayer:self.graph.plotAreaFrame];
                    pointInPlotArea.x -= 10;
                    NSDecimal newPoint[2];
                    [self.graph.defaultPlotSpace plotPoint:newPoint forPlotAreaViewPoint:pointInPlotArea];
                    NSDecimalRound(&newPoint[0], &newPoint[0], 0, NSRoundPlain);
                    int x = [[NSDecimalNumber decimalNumberWithDecimal:newPoint[0]] intValue];
                    x--;
                    if (x <= 0)
                        x = 0;
                    else if (x >= [self.currentDatapoints count])
                        x = [self.currentDatapoints count] - 1;
    
                    selectedCoordination2 = x;
                    self.secondLabel.text = [NSString stringWithFormat:@"%@", [self.currentDatapoints objectAtIndex:x]];
                    [secondTouchPlot reloadData];
                    float first = [self.label.text floatValue];
                    float second = [[self.currentDatapoints objectAtIndex:x] floatValue];
                    self.differenceLabel.textColor = (first - second) > 0 ? [UIColor greenColor] : [UIColor redColor];
                    self.differenceLabel.text = [NSString stringWithFormat:@"%f", first - second];
    
                }
            }
        }
        return YES;
    }
    

    And that's the result...

    enter image description here

    This is not optimized code, it's just the idea, as I mentioned above, how to approach this problem.

    Hope it helps...

提交回复
热议问题