2012-04-27 79 views
0

聲明:我是比較新的的iOS編程,我試圖教我的基礎知識,因爲我一起只是爲了好玩去......所以,請溫柔:-)AVAudioPlayer延遲setImage的發生


我正在構建一款應用程序,播放一系列使用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的狀態嗎? – 2012-04-27 16:27:41

+0

不是,它設置在start_playing方法的頂部 - 第1行。 – Drew 2012-04-27 17:21:37

回答

0

您的for loop正在捆綁主線程,使您的UI無響應。不要連續運行for循環,而要將自己設置爲AVAudioPlayer的代理。一旦音頻播放器完成播放,它將向代表發送消息- (void) audioPlayerDidReachEnd;(您必須執行該操作)。然後,您可以播放該實現中隊列中的下一個音頻文件。無論如何,你真的想成爲代表。AVAudioPlayer將發送您的委託消息以進行中斷(如來電)並解碼錯誤。你想優雅地處理這些事件。

我認爲音頻播放良好的原因是它具有更高的優先級,並在單獨的線程上運行。 UI變爲無響應的原因是即使動畫/ UI更改發生在單獨的線程上,它們也是從主線程啓動的。但是所有UI更改都排隊到運行循環的末尾(因此可以進行優化)。但是,該運行循環永不結束,因爲您的for loop永遠不會結束,直到播放所有音頻文件。音頻文件可以按順序播放,因爲它們是在for loop中啓動的,並在單獨的線程上運行。說得通?一般來說,你真的不想捆綁主線程。

+0

謝謝,你的建議幫了大忙。 最後,我完全移除了for循環和while循環,並且最終逐個遍歷每個聲音,並在每個之前的聲音完成後敲擊新的播放方法。 謝謝! – Drew 2012-05-10 18:20:40