2012-04-27 3 views
0

免責を起こってからsetImageを遅らせる:私は、iOSプログラミングの比較的新しいんだ、と私はちょうど楽しみのために一緒に行くように自分自身の基本を教えしようとしています...そうAVAudioPlayerは


:-)優しくして私はAVAudioplayerを使用して一緒につながっている一連の.mp3ファイルを再生するアプリケーションを構築しています。これまでのところ、その部分はうまく働いています。 IBActions、およびIBOutletsが接続されました。ボタンをクリックすると、オーディオが再生されます。

私の問題は次のとおりです。 私の再生ボタンがmain.storyboardに直接追加され、設定され、カスタムがInterface Builderで定義された初期状態になりました。再生をクリックすると、再生中であることを示すためにボタンの画像を変更したいと考えています。しかし、オーディオが始まるとすぐに、ビューが一時停止されているかのように見えます。オーディオが再生されるまで、ボタン画像は同じままです。それでは、ボタン画像自体は更新されますが、ほとんど役に立ちません。

また、この特定のボタンには付けられていない別のランダムUIImageViewのイメージを設定しようとしました。同じ経験。 playAudioArrayメソッドをコメントアウトするとすぐに、ボタンのスワップがすぐに機能します。


    -(IBAction)start_playing:(UIButton*)pressed_button { 
    [_btn_start setImage:[UIImage imageNamed:@"btn_on-active"] forState:UIControlStateNormal]; 

    [self playAudioArray]; 
    } 

私は十分に進むことを望んでいます...任意の思考/コメント/提案?

おかげで百万 - ドリュー

更新:

私はloppで私のオーディオプレーヤーを持っていたときにビューを更新すると、故障していることがわかりました。このコードは正常に動作します...


    if (audioPlayer.playing == YES) {

[audioPlayer pause]; 
[sender setImage:[UIImage imageNamed:@"btn_on.png"] forState:UIControlStateNormal]; 
[_btn_stop setImage:[UIImage imageNamed:@"btn_off.png"] forState:UIControlStateNormal]; 

} else { 

NSString *path = [[NSBundle mainBundle] pathForResource:@"audio_file1" ofType:@"mp3"]; 
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]; 
audioPlayer.volume = 1.0; 
audioPlayer.numberOfLoops = 0; 
[audioPlayer setMeteringEnabled: YES]; 
[audioPlayer play]; 


//changes the image when the button is pressed 
[sender setImage:[UIImage imageNamed:@"btn_on.png"] forState:UIControlStateNormal]; 
[_btn_stop setImage:[UIImage imageNamed:@"btn_off.png"] forState:UIControlStateNormal]; 

} 

しかし、このコードは以下ませんしません。


    } else {

//changes the image when the button is pressed 
[sender setImage:[UIImage imageNamed:@"btn_on.png"] forState:UIControlStateNormal]; 
[_btn_stop setImage:[UIImage imageNamed:@"btn_off.png"] forState:UIControlStateNormal]; 

NSArray *theSoundArray = [NSArray arrayWithObjects:@"audio1",@"audio2",@"audio3",nil]; 

for (int i = 0; i < totalSoundsInQueue;) { 

NSString *sound = [theSoundArray objectAtIndex:i]; 

// Wait until the audio player is not playing anything 
while(![audioPlayer isPlaying]){ 

NSString *path = [[NSBundle mainBundle] pathForResource:@"mom" ofType:@"mp3"]; 
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]; 
audioPlayer.volume = 1.0; 
audioPlayer.numberOfLoops = 0; 
[audioPlayer setMeteringEnabled: YES]; 
[audioPlayer play]; 

i++; 

}   

} 

} 

オーディオは罰金果たしている、すべての私の音をループし、エラーは発生しません。私のボタンの「オン状態」は、ループ再生が完了した後にのみ設定されます。私はこれをさまざまなタイプのループ方法で試しました。それぞれのために、私がループを始めるたびに、オーディオの再生は素晴らしいですが、ディスプレイはすべての焦点を失います。

私は思い出します。ループに入ると、「停止」ボタンがクリック可能(タップ可能)な性質を失います。ループが終了するまで私がループしていない場合、停止ボタンは問題なく動作します。

申し訳ありません私はここで全く新しいミスをしています...考え/コメント誰ですか?

+0

'playAudioArray'メソッドは' _btn_start'の状態を設定していますか? –

+0

いいえ、start_playingメソッドの最初に設定されています - 1行目。 – Drew

答えて

0

お客様のfor loopがメインスレッドを抱いているため、UIが応答しなくなります。 forループを継続的に実行する代わりに、AVAudioPlayerのデリゲートとして自分自身を設定します。オーディオプレーヤーの再生が終了すると、デリゲートにメッセージ- (void) audioPlayerDidReachEnd;(実装する必要があります)が送信されます。その後、そのインプリメンテーションのキューで次のオーディオファイルを再生できます。とにかく、あなたは本当に代議員として自分自身を設定したい。AVAudioPlayerは、(コールの着信などの)中断やエラーのデリゲートについてデリゲートメッセージを送信します。あなたはこれらのイベントを優雅に処理したいと思っています。

私は、オーディオが正常に再生されている理由は、優先順位が高く、別のスレッドで実行されていると思います。 UIが応答しなくなるのは、アニメーション/ UIの変更が別のスレッドで発生しても、メインスレッドから開始されたためです。しかし、すべてのUIの変更は、実行ループの最後にキューイングされます(最適化を行うことができます)。ただし、すべてのオーディオファイルが再生されるまで、for loopが終了しないため、実行ループは終了しません。オーディオファイルは、for loopで開始され、別のスレッドで実行されるため、順番に再生することができます。意味がありますか?一般的に、あなたは本当にメインスレッドを縛りたくありません。

+0

ありがとうございます、あなたの提案は1トン助けました。 最後に、forループとwhileループの両方を完全に削除し、各サウンドを個別に処理して、それぞれのサウンドが終了した後に新しい再生方法を打ち上げました。 ありがとうございます! – Drew