2012-08-15 52 views
0

我會嘗試盡我所能地解釋我的問題。 我有一架鋼琴,可以播放並錄製歌曲,你彈奏的每一個鋼琴按鈕都會突出顯示。問題是我有另一個按鈕來播放我錄製的歌曲,但我想要的是突出顯示正在播放的鋼琴的每個按鈕。 下面是函數的一部分,我已經編碼:功能在iOS中結束之前的高亮按鈕

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

     } 

你可以看到,在每一個音符,我強調的是音符的按鈕,但我有問題是按鈕只強調一次功能結束,所以我的筆記將在旋律完成後突出顯示。 我希望有人能幫助我。

回答

-1

嘗試用

[self performSelectorInBackground:@selector(myMethod:) withObject:_myParamsArray]; 

打電話給你的highlightning代碼在一個單獨的線程例如:

... 
     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]; 
} 

是否有任何代碼的拼寫錯誤,請原諒。我在編輯器中修改了它。

你需要修改我的例子,以取消激活其它高亮顯示的按鈕但應該是沒有問題的

+0

UI元素只能在主線程上進行更新,而不是在後臺線程。所以這是行不通的。 – 2012-08-15 11:35:20

0

的問題是sleep(1)電話。用戶界面元素只有在play函數返回主運行循環時纔會更新。

使用這種同步方法進行計時是一個糟糕的設計。例如,您可以使用NSTimer異步等待一秒鐘。但是這需要對play方法進行重大設計。

0

您必須有某種計時器對象(請參閱NSTimer)才能與音樂同步,然後根據需要突出顯示按鈕(請確保使用主線程)。

這樣做不會影響當前正在按下的按鈕。

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];}); 
}