我会尽可能清楚地解释我的问题。 我有一把钢琴,你可以演奏并录制你所做的歌曲,以及你演奏的钢琴的每个按钮,这个按钮都会突出显示。问题是我有另一个按钮来播放我录制的歌曲,但我想要的是突出显示正在发声的钢琴的每个按钮。 这是我编写的函数的一部分:
- (IBAction)play:(id)sender
{
for(NSString *string in [Singleton sharedInstance].notesMusicals)
if([string isEqualToString:@"doMenor"]){
UIImage *buttonImage = [UIImage imageNamed:@"do-menor_ON.png"];
[doMenorButton setImage:buttonImage forState:UIControlStateNormal];
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle,(CFStringRef) @"Do_m", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
//doMenorButton.highlighted = YES;
sleep(1);
}
else if([string isEqualToString:@"Re"]){
UIImage *buttonImage = [UIImage imageNamed:@"do-menor_OFF.png"];
[doMenorButton setImage:buttonImage forState:UIControlStateNormal];
UIImage *buttonImage1 = [UIImage imageNamed:@"re_ON.png"];
[reButton setImage:buttonImage1 forState:UIControlStateNormal];
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle,(CFStringRef) @"Re", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
sleep(1);
}
你可以看到,在每个音符中,我都会突出显示该音符的按钮,但我遇到的问题是该功能结束时该按钮才会突出显示,所以在旋律结束后我的所有音符都会突出显示。 我希望有人可以帮助我。
答案 0 :(得分:0)
问题是sleep(1)
电话。只有在play
函数返回主runloop时才会更新用户界面元素。
使用这种同步方法进行计时是一种糟糕的设计。例如,您可以使用NSTimer
异步等待一秒钟。但这需要重新设计play
方法。
答案 1 :(得分:0)
您必须拥有某种计时器对象(请参阅NSTimer
)以与音乐同步,然后根据需要突出显示按钮(确保使用主线程)。
这样做不会影响当前按下的按钮。
答案 2 :(得分:0)
试试这个(我没有尝试编译这么多拼写错误等):
// Assumes ARC. Note that since the block retains "self", you won't get dealloc'd
// until the queued block has run. If the user wants to stop the music set "cancel = YES"
@implementation MyClass
{
NSArray *notes;
NSUInteger theNote;
BOOL cancel;
}
- (void)playOneSound
{
if(cancel) return;
if([string isEqualToString:@"doMenor"]){
UIImage *buttonImage = [UIImage imageNamed:@"do-menor_ON.png"];
[doMenorButton setImage:buttonImage forState:UIControlStateNormal];
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle,(CFStringRef) @"Do_m", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
//doMenorButton.highlighted = YES;
}
else if([string isEqualToString:@"Re"]){
UIImage *buttonImage = [UIImage imageNamed:@"do-menor_OFF.png"];
[doMenorButton setImage:buttonImage forState:UIControlStateNormal];
UIImage *buttonImage1 = [UIImage imageNamed:@"re_ON.png"];
[reButton setImage:buttonImage1 forState:UIControlStateNormal];
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle,(CFStringRef) @"Re", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
// now going to queue up another sound to play in 1 second, leaving your UI responsive
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{ [self playOneSound];} );
}
- (IBAction)play:(id)sender
{
notes = [Singleton sharedInstance].notesMusicals;
theNote = 0;
cancel = NO;
// by defering til the next runLoop round, the play button gets to unhilite
dispatch_async(dispatch_get_main_queue(), ^{ [self playOneSound];} );
}
答案 3 :(得分:-1)
尝试使用
在单独的主题中调用突出显示的代码[self performSelectorInBackground:@selector(myMethod:) withObject:_myParamsArray];
例如:
...
else if([string isEqualToString:@"Re"]){
[self performSelectorInBackground:@selector(highlight:) withObject:myButton];
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle,(CFStringRef) @"Re", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
sleep(1);
}
...
-(void) highlight:(UIButton)*button
{
UIImage *buttonImage1 = [UIImage imageNamed:@"re_ON.png"];
[button setImage:buttonImage1 forState:UIControlStateNormal];
}
请原谅代码中是否有拼写错误。我在编辑器中修改了它。
你需要修改我的示例,以便取消激活其他突出显示的按钮,但这应该没问题