views:

294

answers:

2

So here's a weird question. I have a UIImageView that responds to touchesMoved & touchesBegan, it works perfectly. The main thing I'm having an issue with is if you put your finger down on say image1 and then with that finger still down on image1 you would press image2 with your other finger.

In turn this would fire image1 again. Dont want that to happen. I want to be able to use Multi Touch when pushing both images at the same time and not firing them over and over. There must be something I have to add to stop that from happening.

Code:

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSSet *allTouches = [event allTouches]; 
    for (UITouch *touch in allTouches) 
    { 
        CGPoint location = [touch locationInView:touch.view];
        if(CGRectContainsPoint(image1.frame, location) && lastButton != image1) {
            //Play Sound
            NSString *path = [[NSBundle mainBundle] pathForResource:@"sound1" 
                                                             ofType:@"wav"];
            SystemSoundID soundID;
            AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path]
                                             , &soundID);
            AudioServicesPlaySystemSound (soundID); 
            //
            lastButton = image1;
        }
        if(CGRectContainsPoint(image2.frame, location) && lastButton != image2) {
            //Play Sound
            NSString *path = [[NSBundle mainBundle] pathForResource:@"sound2" 
                                                             ofType:@"wav"];
            SystemSoundID soundID;
            AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path]
                                             , &soundID);
            AudioServicesPlaySystemSound (soundID); 
            //
            lastButton = image2;
        }

    }

And for the touchesMoved:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint location = [touch locationInView:touch.view];
        if(CGRectContainsPoint(image1.frame, location) && lastButton != image1) {
            //Play Sound
            NSString *path = [[NSBundle mainBundle] pathForResource:@"sound1" 
                                                             ofType:@"wav"];
            SystemSoundID soundID;
            AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path]
                                             , &soundID);
            AudioServicesPlaySystemSound (soundID); 
            //
            lastButton = image1;
        }
        if(CGRectContainsPoint(image2.frame, location) && lastButton != image2) {
            //Play Sound
            NSString *path = [[NSBundle mainBundle] pathForResource:@"sound2" 
                                                             ofType:@"wav"];
            SystemSoundID soundID;
            AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path]
                                             , &soundID);
            AudioServicesPlaySystemSound (soundID); 
            //
            lastButton = image2;
        }

    }

Lastly here are the finals:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    lastButton = nil;
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [self touchesEnded:touches withEvent:event];
}

So I just need to make it so if I'm holding down one of the images and then press another and release it again and push it again that it stops firing the first image I am pressing down on.

A: 

Use the touches NSSet that is passed into your touchesBegan method, rather than allTouches from the event.

Jason Foreman
How would you write that out? I tried using:-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ UITouch *touch = [[event touchesForView:self.view] anyObject]; CGPoint location = [touch locationInView:touch.view];I dont think that's what you meant though. Mind writing it out so I understand exactly. Thanks.
AndrewDK
One of the parameters to that method is an NSSet* that is the touches that are affected. So in -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {...}just use *that* touches variable. That set will contain the touch(es) that began during that event.-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ UITouch *touch = [touches anyObject]; // whatever you want to do with touch...}
Jason Foreman
Yeah thanks for clarifying, it still doesnt work. When I have a finger down on one image and then press another it still will fire that. As well when I try and push 2 images at once they fire and then the first one hit will fire again with that touch. It's really weird.
AndrewDK
A: 

All views that are involved will receive all the touches (in the NSSet as mentioned by Jason). It's up to each view (up to you, that is) to selected that touches you are interested in. So you have to check if each touch is inside the view's limits, and try to correlate the touch to the last one received. Since you get the touches in a set, you cannot rely on their order to calculate how much they moved, for example. You have to save the coordinates of the last touch and select the touch that is closest and assume that it's the same finger that has moved.

Felixyz
A bit confusing, I see what you mean. Ill have to play around around with it a bit more.
AndrewDK