在关闭动画之前运行 UIAlertController 完成处理程序块

问题描述 投票:0回答:2

我正在使用

UIAlertController
设置一个非常标准的操作表:

    let alert = UIAlertController(title: "title",
                                  message: nil,
                                  preferredStyle: .actionSheet)

    alert.addAction(
        UIAlertAction(title: "button",
                      style: .default,
                      handler: { _ in
                        MediaPlayer.playSound(.click)
                        // The above line just uses AVAudioPlayer to play
                        // an MP3 file. Its implementation isn't relevant
                        // to the question and can be assumed to be correct.
    }))

当我按下按钮时,警报消失,然后完成处理程序运行并播放声音。由于警报的解除动画需要一段时间,因此在我按下按钮和播放声音之间存在非常明显的延迟;当声音开始时,警报甚至不再可见。

有没有办法在按下按钮时立即播放声音,而不是等到关闭动画完成为止?

此外,是否有一个原因导致没有简单的方法来做到这一点? IE。苹果是否反对人们在警报按钮中添加点击声音?

ios swift cocoa-touch uialertcontroller
2个回答
3
投票

对此你基本上无能为力。一旦 UIAlertController 替换了 UIAlertView,用户点击和按钮操作处理程序运行之间的延迟就很明显:

UIAlertController 关闭很慢

实际上,您正在尝试做一些 Apple 不希望您做的事情,即将声音与警报控制器按钮相关联。

我对这类事情的解决方案很简单:不要使用 UIAlertController。构建一个自定义呈现的视图控制器非常容易,它看起来就像像 UIAlertController 的视图,事实上 UIAlertController 呈现的视图控制器。所以就自己动手吧。现在按钮是你的了,你可以检测到点击并用声音响应,然后关闭,没问题。


2
投票

而不是像 Matt 建议的那样重建

UIAlertController
(并在每次调整时更新它以匹配 iOS),我建议简单地对其进行子类化。您可以给它一段您想要在它消失时运行的代码块。例如:

class CustomAlertController: UIAlertController {
    var onDisappear: (() -> Void)?

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        onDisappear?()
    }
}

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

let controller = CustomAlertController(title: "Title", message: nil, preferredStyle: .actionSheet)
controller.onDisappear = {
    // play sound here
}
© www.soinside.com 2019 - 2024. All rights reserved.