How to track multiple touches in Xcode

后端 未结 1 1068
天涯浪人
天涯浪人 2020-12-20 10:29

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,

相关标签:
1条回答
  • 2020-12-20 11:10

    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:

    Hope this helps :)

    0 讨论(0)
提交回复
热议问题