0

I have some multitouch questions

this is one part of my code in .m file

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint pt = [touch locationInView:self.view];

if(pt.x>634 && pt.x<733 && pt.y >64 && pt.y<145)
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"si" ofType:@"mp3"];
    theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
    theAudio.delegate = self;
    [theAudio play];
}

if(pt.x>634 && pt.x<733 && pt.y >195 && pt.y<276)
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"la" ofType:@"mp3"];
    theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
    theAudio.delegate = self;
    [theAudio play];
}


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

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"rest" ofType:@"mp3"];
    theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
    theAudio.delegate = self;
    [theAudio play];
}

I hope this can work.

Actually,the second "if ((range) &&(range)) " part doesn't work. Can anyone tell me the solution?

The first range works, and I want the second range to play "la.mp3", but when 2 fingers touch down, it doesn't play any music.

mackworth
  • 5,873
  • 2
  • 29
  • 49
施毛佑
  • 5
  • 3

2 Answers2

1

Sorry, this is going to be a complete edit of the answer since I can't manage to delete the last one. I made a major reading error and I need to write a new answer. You must not use [touches anyObject] because that will not reliably give you the touch you want in a multitouch system.

You must use [[touches allObjects] objectAtIndex:#] to extract the touch. The touches will be in there in the order they came.

borrrden
  • 33,256
  • 8
  • 74
  • 109
  • sorry,I have fix my code: `-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ UITouch *touch = [[touches allObjects] objectAtIndex:#]; CGPoint pt = [touch locationInView:self.view];` I know "#" must be one number but if I have 7 buttons at most,so should I type 7 or...? whatever I type 1 or 7 it still doesnt work>< I'm very new so I dont understand your answer completely,sorry – 施毛佑 May 10 '12 at 15:09
  • The numbers are the touches themselves (If you touch with two fingers you will get 2), not the buttons or something. The point is you need to check all the touches and your code only checks the first one. The easiest way to do that is probably the loop mentioned in the other answer. – borrrden May 10 '12 at 23:32
  • sorry,I got a problem.This is my code in file.m: `-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ for (UITouch * touch in touches) { CGPoint pt = [touch locationInView:self.view]; if([[touches allObjects] objectAtIndex:1] && ((pt.x>634 && pt.x<733 && pt.y >64 && pt.y<145))) { NSString *path = [[NSBundle mainBundle] pathForResource:@"si" ofType:@"mp3"]; theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]; theAudio.delegate = self; [theAudio play]; } ` – 施毛佑 May 12 '12 at 03:55
  • `if([[touches allObjects] objectAtIndex:2] && ((pt.x>634 && pt.x<733 && pt.y >64 && pt.y<145)&&(pt.x>634 && pt.x<733 && pt.y >195 && pt.y<276))) { NSString *path = [[NSBundle mainBundle] pathForResource:@"la" ofType:@"mp3"]; theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]; theAudio.delegate = self; [theAudio play]; } } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{} ` – 施毛佑 May 12 '12 at 03:57
  • `-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ NSString *path = [[NSBundle mainBundle] pathForResource:@"rest" ofType:@"mp3"]; theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]; theAudio.delegate = self; [theAudio play]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.view.multipleTouchEnabled=YES; } ` and run simulator it will stop at "main.m" he says"Thread 1:Program received signal: "SIGABRT"." when I touch my simulator. – 施毛佑 May 12 '12 at 03:57
  • Try doing it the way mackworth describes it. `for(UITouch *touch in touches) { CGPoint pt = [touch locationInView:self]; //... }` – borrrden May 12 '12 at 09:55
  • sorry,I think its my code problem,the".view" doesnt fix it,thank you. – 施毛佑 May 12 '12 at 16:26
0

You need to re-read the docs on MultiTouch Events. First, you need to set the multipleTouchEnabled property of the view to YES. Secondly, you're only getting one touch event each time through, as you're setting

UITouch *touch = [touches anyObject];   

Instead try

for (UITouch * touch in touches) {

to execute your code on each touch in the current set.

Secondly, I'm concerned that your AVAudioPlayer will be released upon the termination of TouchDidBegin; I would think this would cancel the rest of the playback. It should probably be a property. Also, AVAudioPlayer can only play one audio track at a time, so you'll want to have two different ones hanging around.

Another (better) alternative would be to ditch touches altogether and just use buttons. You can be notified when a button is pressed down (starting a note) and when a button is released (keep track of which ones are still down, and if you're at the last one down, then play the "rest.mp3").

mackworth
  • 5,873
  • 2
  • 29
  • 49