0

免責事項: 私は iOS プログラミングに比較的慣れていないので、楽しみのために基本を独学で学ぼうとしています... だから優しくしてください :-)


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

先に進むのに十分なだけ残っていることを願っています.何か考え/コメント/提案はありますか??

どうもありがとう - ドリュー

#

アップデート:

オーディオ プレーヤーが障害になっていると、ビューの更新がうまくいかないことがわかりました。このコードは正常に動作します...


    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++;

}        

}

}

オーディオは正常に再生され、すべてのサウンドがループされ、エラーは発生しません。ただ、ボタンの「オン状態」は、ループの再生が完了した後にのみ設定されます。さまざまな種類のループ方法でこれを試しました。For, for each, while... サウンドのループを開始するたびに、オーディオの再生はうまく機能しますが、ディスプレイのフォーカスがすべて失われます。

それは私に思い出させます。ループに入ると、「停止」ボタンがクリック可能 (タップ可能) の性質を失います。ループの実行が完了するまで。ループしていない場合、停止ボタンは問題なく機能します。

ここで完全な初心者の間違いを犯していたら申し訳ありません... 考え/コメントはありますか?

4

1 に答える 1

0

メインスレッドfor loopを拘束しているため、UI が応答しなくなります。for ループを継続的に実行する代わりに、自分自身を AVAudioPlayer のデリゲートとして設定します。オーディオ プレーヤーの再生が完了すると、デリゲートにメッセージが送信されます- (void) audioPlayerDidReachEnd;(実装する必要があります)。次に、その実装でキュー内の次のオーディオ ファイルを再生できます。とにかく、あなたは自分自身をデリゲートとして設定したいと思っています。AVAudioPlayer は、割り込み (着信など) のデリゲート メッセージを送信し、エラーをデコードします。これらのイベントを適切に処理する必要があります。

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

于 2012-05-04T14:27:44.703 に答える