Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
893 views
in Technique[技术] by (71.8m points)

ios - How to track multiple touches in Xcode

Recently I'm making an app that can drag multiple objects at the same time. I had tried to use UIPanGestureRecognizer to get the coordinates of finger touches, but I couldn't know which touch belongs to which finger.

I need to support four fingers panning simultaneously without interfering with each other using Objective-C.

I had searched for the soulution for a while, but the answers they show didn't work for me. Any help would be appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've struggled with the same problem for quite a long time and finally solved it. The following is the code in my DrawView.m, which is a subclass of UIView that is able to support drawings using drawRect:.

#import "DrawView.h"

#define MAX_TOUCHES 4

@interface DrawView() {

    bool touchInRect[MAX_TOUCHES];
    CGRect rects[MAX_TOUCHES];
    UITouch *savedTouches[MAX_TOUCHES];
}

@end

@implementation DrawView

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        // Initialization code
        self.multipleTouchEnabled = YES;
        for (int i=0; i<MAX_TOUCHES; i++) {
            rects[i] = CGRectMake(200, 200, 50 ,50);
            savedTouches[i] = NULL;
            touchInRect[i] = false;
        }
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    // Drawing code
    [[UIColor blueColor] set];
    CGContextRef context = UIGraphicsGetCurrentContext();

    for (int i=0; i<MAX_TOUCHES; i++) {
        CGContextFillRect(context, rects[i]);
        CGContextStrokePath(context);
    }
}

#pragma mark - Handle Touches

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    NSArray *allTouches = [touches allObjects];
    for (int i=0; i<[allTouches count]; i++) {
        UITouch *touch = allTouches[i];
        CGPoint newPoint = [touch locationInView:self];

        for (int j=0; j<MAX_TOUCHES; j++) {
            if (CGRectContainsPoint(rects[j], newPoint) && !touchInRect[j]) {
                touchInRect[j] = true;
                savedTouches[j] = touch;
                break;
            }
        }
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    NSArray *allTouches = [touches allObjects];
    for (int i=0; i<[allTouches count]; i++) {
        UITouch *touch = allTouches[i];
        CGPoint newPoint = [touch locationInView:self];

        for (int j=0; j<MAX_TOUCHES; j++) {
            if (touch == savedTouches[j]) {
                rects[j] = [self rectWithSize:rects[j].size andCenter:newPoint];
                [self setNeedsDisplay];
                break;
            }
        }
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    NSArray *allTouches = [touches allObjects];
    for (int i=0; i<[allTouches count]; i++) {
        UITouch *touch = allTouches[i];

        for (int j=0; j<MAX_TOUCHES; j++) {
            if (touch == savedTouches[j]) {
                touchInRect[j] = false;
                savedTouches[j] = NULL;
                break;
            }
        }
    }
}


- (CGRect)rectWithSize:(CGSize)size andCenter:(CGPoint)point {
    return CGRectMake(point.x - size.width/2, point.y - size.height/2, size.width, size.height);
}

@end

I set the MAX_TOUCHES as 4, so there will be four objects on the screen. The basic concept of this is to store each UITouch ID in the savedTouches array when touchesBegan:: is called, and later compare each ID with the touches on screen when touchesMoved:: called.

Just paste the code into your .m file and it'll work. The sample result is shown here:

enter image description here

Hope this helps :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...