Проблемы с созданием пользовательского интерфейса iPhone Piano

Я пытаюсь создать приложение для фортепиано на iPhone. Я создал 14 различных UIImageViews в Интерфейсном Разработчике для представления ключей. С помощью touchesBegan, touchesMoved, touchesEnded и touchesCancelled я затем попытался воспроизвести аудиофайлы.

Итак, как только звук воспроизводится, когда вы двигаете пальцем (touchesMoved), я решил с помощью NSMutableArray.

Код (я скопировал только для ключа C, код для остальных ключей такой же) выглядит так:

мой .h файл:

@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

мой .m файл:

#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

(Я заменю "AudioServicesPlaySystemSound" на OpenAL или что-то еще)

Теперь мои проблемы:

Если переместить палец на другую клавишу, не поднимая его, звук воспроизводится, но клавиша остается подсвеченной. Кроме того, если вы снова переместите палец назад, звук не будет воспроизводиться.

Также есть проблемы при нажатии двумя пальцами, просто убери один. Затем снова воспроизводится тон первой клавиши.

Также вы слышите, когда вы нажимаете одну из черных клавиш, а также звук одной из соседних белых клавиш.

В целом, я использовал этот метод для создания пользовательского интерфейса фортепиано для многих проблем, которые я не могу решить в одиночку.

Может быть, есть другой способ запрограммировать все приложение? Или есть у кого-нибудь советы, как я могу решить проблемы?

Спасибо, Джоджос.

PS: Простите за плохой английский, я немец.


person Jojoce    schedule 11.10.2010    source источник


Ответы (1)


Выход UIButton не предназначен для обработки сложных сенсорных взаимодействий, таких как глиссандо и т. Д.

Вы можете попробовать поместить изображение своей клавиатуры в пользовательский подкласс UIView, вычислить прямоугольники попаданий для всех активных областей (несколько прямоугольников для белых клавиш) и использовать обработчик UITouch в подклассе представления для отслеживания всех касаний по отдельности, включая в какие прямоугольники они попадают изначально, переходят в другой, где их отпускают и т. д.

person hotpaw2    schedule 11.10.2010
comment
Спасибо за быстрый ответ! А как тогда клавиши подсветить? А вы могли бы привести мне пример кода, потому что я все еще новичок в программировании? Это было бы очень хорошо. Спасибо - person Jojoce; 11.10.2010