功能在iOS结束前突出显示按钮

时间:2012-08-15 10:13:08

标签: objective-c ios function button highlight

我会尽可能清楚地解释我的问题。 我有一把钢琴,你可以演奏并录制你所做的歌曲,以及你演奏的钢琴的每个按钮,这个按钮都会突出显示。问题是我有另一个按钮来播放我录制的歌曲,但我想要的是突出显示正在发声的钢琴的每个按钮。 这是我编写的函数的一部分:

- (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);

        }

你可以看到,在每个音符中,我都会突出显示该音符的按钮,但我遇到的问题是该功能结束时该按钮才会突出显示,所以在旋律结束后我的所有音符都会突出显示。 我希望有人可以帮助我。

4 个答案:

答案 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];
}

请原谅代码中是否有拼写错误。我在编辑器中修改了它。

你需要修改我的示例,以便取消激活其他突出显示的按钮,但这应该没问题