有关创建 iPhone Piano UI 的问题
我正在尝试创建一个 iPhone 钢琴应用程序。 我在 Interface Builder 中创建了 14 个不同的 UIImageView 来表示按键。然后,我尝试使用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
我将用 OpenAL 或其他内容替换“AudioServicesPlaySystemSound”)
现在我的问题:
如果您将手指移动到另一个键而没有抬起,则会播放声音,但该键仍然突出显示。此外,如果您再次将手指移回,则不会播放任何声音。
另外,按两根手指也有问题,拿开一根就可以了。 然后再次播放第一个键的音调。
当您按下其中一个黑键时,您还会听到相邻白键之一的声音。
总的来说,我使用这种方法创建钢琴 UI 遇到了许多我无法单独解决的问题。
是否有另一种方法来对整个应用程序进行编程? 或者有人告诉我如何解决这些问题吗?
谢谢乔乔斯。
PS:抱歉英语不好,我是德国人。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
UIButton 出口并不意味着处理复杂的触摸交互,例如滑音所需的交互等。
您可以尝试将键盘图形放入自定义 UIView 子类中,计算所有活动区域的点击矩形(白键的多个矩形) ),并在视图子类中使用 UITouch 处理程序来单独跟踪所有触摸,包括它们最初击中的击中矩形、移动到另一个击中的矩形、释放的位置等。
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.