swift 在解除动画之前运行UIAlertController完成块

tquggr8v  于 2024-01-05  发布在  Swift
关注(0)|答案(2)|浏览(143)

我使用UIAlertController设置了一个非常标准的操作表:

  1. let alert = UIAlertController(title: "title",
  2. message: nil,
  3. preferredStyle: .actionSheet)
  4. alert.addAction(
  5. UIAlertAction(title: "button",
  6. style: .default,
  7. handler: { _ in
  8. MediaPlayer.playSound(.click)
  9. // The above line just uses AVAudioPlayer to play
  10. // an MP3 file. Its implementation isn't relevant
  11. // to the question and can be assumed to be correct.
  12. }))

字符串
当我按下按钮时,警报解除,然后完成处理程序运行并播放声音。由于警报的解除动画需要一段时间,因此在我按下按钮和声音播放之间有一个非常明显的延迟;当声音开始时,警报甚至不再可见。
有没有一种方法可以在按下按钮后立即播放声音,而不必等到解除动画完成?
此外,有没有一个原因,没有一个简单的方法来做到这一点?即苹果是反对人们添加点击声音到他们的警报按钮?

kmynzznz

kmynzznz1#

基本上你对此无能为力。当UIAlertController取代了UIAlertView之后,用户点击和按钮动作处理程序运行之间的延迟就很明显了:
UIAlertController dismiss is slow
实际上,你正在尝试做一些苹果不希望你做的事情,即将声音与警报控制器按钮相关联。
我对这类事情的解决方案很简单:不要使用UIAlertController。很容易构建一个自定义的呈现视图控制器,看起来就像一个UIAlertController的视图,实际上UIAlertController就是一个呈现视图控制器。所以只需滚动你自己的按钮。现在按钮是你的了,你可以检测到点击并用声音响应,然后关闭,没有问题。

n1bvdmb6

n1bvdmb62#

与其像Matt建议的那样重建UIAlertController(并在每次调整时更新它以匹配iOS),我建议简单地将其子类化。您可以给予它一段代码,以便在它消失时运行。例如:

  1. class CustomAlertController: UIAlertController {
  2. var onDisappear: (() -> Void)?
  3. override func viewWillDisappear(_ animated: Bool) {
  4. super.viewWillDisappear(animated)
  5. onDisappear?()
  6. }
  7. }

字符串
然后,您可以在显示警报控制器之前设置此块:

  1. let controller = CustomAlertController(title: "Title", message: nil, preferredStyle: .actionSheet)
  2. controller.onDisappear = {
  3. // play sound here
  4. }

展开查看全部

相关问题