AVAudioPlayer延迟了setImage的发生

时间:2012-04-27 15:47:39

标签: objective-c ios loops view avaudioplayer

免责声明:我对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];
    }

我希望我已经离开了......任何想法/意见/建议??

万分感谢 - 德鲁

更新

我发现当我的音频播放器处于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];

}

但是这段代码不会低于。

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

}

音频播放正常,循环播放所有声音,不会发生错误。只是,我的按钮的“开启状态”仅在完成循环播放后设置。我已经尝试了许多不同类型的循环方法。对于每一个,同时...每次我开始循环播放声音时,音频播放效果很好,但显示器失去了所有焦点。

这让我想起了。一旦我进入循环,我的“停止”按钮就会失去它可点击(可点击)的特性。直到循环完成运行。如果我不在循环中,停止按钮工作正常,没有问题。

对不起,如果我在这里犯了一个新的错误...想法/评论任何人?

1 个答案:

答案 0 :(得分:0)

你的for loop正在占用主线程,使你的UI无法响应。而不是连续运行for循环,将自己设置为AVAudioPlayer的委托。一旦音频播放器完成播放,它将向代表发送消息- (void) audioPlayerDidReachEnd;(您必须实现)。然后,您可以在该实现中播放队列中的下一个音频文件。无论如何,你真的想把自己设定为代表。 AVAudioPlayer将发送您的委托消息以进行中断(如来电)和解码错误。您希望优雅地处理这些事件。

我认为音频播放正常的原因是它具有更高的优先级并且在单独的线程上运行。 UI变得无响应的原因是即使动画/ UI更改发生在单独的线程上,它们也是从主线程启动的。但是所有UI更改都排队到运行循环结束(因此可以进行优化)。但是,该运行循环永远不会结束,因为在播放所有音频文件之前,for loop永远不会结束。音频文件可以按顺序播放,因为它们是在for loop中启动并在单独的线程上运行的。说得通?一般来说,你真的不想占用主线程。