views:

39

answers:

1

Hi,

I'm trying to create an iPhone piano app. I have created 14 different UIImageViews in Interface Builder, to represent the keys. With touchesBegan, touchesMoved, touchesEnded and touchesCancelled I then tried to play the audio files.

So once the sound is played when you move your finger (touchesMoved) I have solved with a NSMutableArray.

The code (I have copied only for C Key, the code for the other keys is the same) looks like this:

my .h File:

@interface PianoViewController : UIViewController {
    IBOutlet UIImageView *pianoButtonC;
    IBOutlet UIImageView *pianoButtonCC;
    IBOutlet UIImageView *pianoButtonD;
    IBOutlet UIImageView *pianoButtonDb;
    IBOutlet UIImageView *pianoButtonDbDb;
    IBOutlet UIImageView *pianoButtonE;
    IBOutlet UIImageView *pianoButtonEb;
    IBOutlet UIImageView *pianoButtonF;
    IBOutlet UIImageView *pianoButtonG;
    IBOutlet UIImageView *pianoButtonGb;
    IBOutlet UIImageView *pianoButtonH;
    IBOutlet UIImageView *pianoButtonHb;
    CGPoint location;
    NSMutableArray *lastButtons;
    UITouch *touch;
}

@end

my .m File:

#import "PianoViewController.h"
@implementation PianoViewController

-(void)viewDidLoad {
    [super viewDidLoad];
 [self.view setMultipleTouchEnabled:YES];
    lastButtons = [[NSMutableArray alloc] init]; 
    [lastButtons insertObject:@"notPressedC" atIndex:0];
}

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

    for(touch in [event allTouches]){   

        if(CGRectContainsPoint(pianoButtonC.frame, [touch locationInView:touch.view]) && [lastButtons containsObject:@"notPressedC"]) {
            [pianoButtonC setHighlighted: YES];
            NSString *path = [[NSBundle mainBundle] pathForResource:@"pianoC"ofType:@"wav"];
            SystemSoundID soundID;
            AudioServicesCreateSystemSoundID((CFURLRef) [NSURL fileURLWithPath:path], &soundID);
            AudioServicesPlaySystemSound (soundID);

            [lastButtons replaceObjectAtIndex:0 withObject:@"pressedC"];
        }

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


    for(touch in [event allTouches]){   

        if(CGRectContainsPoint(pianoButtonC.frame, [touch locationInView:touch.view]) && [lastButtons containsObject:@"notPressedC"]) {
            [pianoButtonC setHighlighted: YES];
            NSString *path = [[NSBundle mainBundle] pathForResource:@"pianoC"ofType:@"wav"];
            SystemSoundID soundID;
            AudioServicesCreateSystemSoundID((CFURLRef) [NSURL fileURLWithPath:path], &soundID);
            AudioServicesPlaySystemSound (soundID);

            [lastButtons replaceObjectAtIndex:0 withObject:@"pressedC"];
        }

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

    [lastButtons replaceObjectAtIndex:0 withObject:@"notPressedC"];
    [pianoButtonC setHighlighted: NO];
}


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

    [self touchesEnded:touches withEvent:event];

}

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationLandscapeRight
            );
}


- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;


}


- (void)dealloc {
    [super dealloc];
    [lastButtons release];

}

@end

(I will replace the "AudioServicesPlaySystemSound" with OpenAL or something else)

Now my problems:

If you move the finger to another key without him lift, the sound is played, but the key remains highlighted. Besides, if you move back the finger again, no sound is played.

Also, there are problems when you press two fingers, just take one away. Then the tone of the first key is played again.

Also you hear when you press one of the black keys, also the sound one of the adjacent white keys.

Overall, I have using this metod to create a piano UI many problems that I can not solve alone.

Is there perhaps another way to program the whole app? Or has anyone tips on how I can solve the problems?

Thanks Jojoce.

PS: Sorry for the bad English, I'm German.

A: 

The UIButton outlet is not meant to handle complex touch interactions such as required for glissando, etc.

You might try putting a graphic of your keyboard in a custom UIView subclass, calculating the hit rectangles for all the active areas (multiple rectangles for the white keys), and using a UITouch handler in the view subclass to track all the touches individually, including what hit rectangles they initially hit, get moved across to another, where they are released, and etc.

hotpaw2
Thanks for the quick reply!And how can I highlight the keys then?And you could give me a code example because I am still a beginner in programming? That would be very very nice.Thanks
Jojoce