0

私は自分の問題をできるだけ明確に説明しようとします。私はあなたが演奏して歌を録音できるピアノを持っています、そしてあなたが演奏するピアノのすべてのボタン、このボタンはハイライトされています。問題は、録音した曲を再生するための別のボタンがあることですが、必要なのは、鳴っているピアノのすべてのボタンを強調表示することです。これが私がコーディングした関数の一部です:

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

4 に答える 4

0

問題はsleep(1)電話です。playユーザーインターフェイス要素は、関数がメインの実行ループに戻ったときにのみ更新されます。

タイミングにこの同期方式を使用するのは悪い設計です。NSTimerたとえば、非同期で1秒間待機するために使用できます。ただし、これにはplayメソッドの大幅な再設計が必要です。

于 2012-08-15T11:34:28.800 に答える
0

NSTimer音楽と同期し、必要に応じてボタンを強調表示するには、何らかのタイマーオブジェクト(を参照)が必要になります(これにはメインスレッドを使用してください)。

これを行っても、現在押されているボタンには影響しません。

于 2012-08-15T11:46:30.293 に答える
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];} );
}
于 2012-08-15T11:47:34.837 に答える
-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];
}

コードにタイプミスがある場合は、失礼します。ここでエディターで変更しました。

他の強調表示されたボタンを非アクティブにするには、例を変更する必要がありますが、問題はありません。

于 2012-08-15T11:28:36.210 に答える