swift 快速-最好的方式来显示警报与加载指示器后,立即点击按钮?

fhity93d  于 2023-02-03  发布在  Swift
关注(0)|答案(4)|浏览(134)

我尝试使用主线程显示,但它没有工作,任何想法,为什么警报不显示了吗?

@IBAction func updateData(_ sender: Any) {
    let alert = UIAlertController(title: "Updating data", message: "Please wait...", preferredStyle: .alert)
    alert.view.tintColor = UIColor.black
    let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 10,y: 5,width: 50, height: 50)) as UIActivityIndicatorView
    loadingIndicator.hidesWhenStopped = true
    loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
    loadingIndicator.startAnimating();

    alert.view.addSubview(loadingIndicator)
    DispatchQueue.main.async {
        self.present(alert, animated: true)

    }
cclgggtu

cclgggtu1#

UIAlertController不能自定义,所以对我来说最好的解决方案是创建一个自定义的UIView XIB,然后在我需要的ViewController上安装它。
XIB视图可能如下所示:

然后创建一个CustomAlertLoadingView.swift文件,该文件的子类为UIView,将其与XIB关联并创建IBOutlets
要在任何ViewController中显示它,只需创建此扩展

extension UIViewController {
     func presentAlert(title: String) {
        let nib = UINib(nibName: "CustomAlertLoadingView", bundle: nil)
        let customAlert = nib.instantiate(withOwner: self, options: nil).first as! CustomAlertLoadingView

        customAlert.tag = 12345
        customAlert.titleAlertLabel.text = title
        customAlert.indicator.startAnimating()

        let screen = UIScreen.main.bounds
        customAlert.center = CGPoint(x: screen.midX, y: screen.midY)

        self.view.addSubview(customAlert)
    }
}

使用self.yourViewController.presentAlert(title:"yourTitle")
要解除警报,请在UIVIewController扩展内创建以下函数

func dismissCustomAlert() {
        if let view = self.view.viewWithTag(12345) {
            view.removeFromSuperview()
        }
}

然后调用self.yourViewController.dismissCustomAlert

hlswsv35

hlswsv352#

我不得不将执行所需的代码放在警报完成回调中

self.present(alert, animated: true, completion: {
        do{...}

})
解决了延迟响应问题

8ftvxx2r

8ftvxx2r3#

我在Xcode上运行了这个代码,没有任何延迟:

@IBAction func updateData(_ sender: UIButton) {
    print("button fire")
    let alert = UIAlertController(title: "Updating data", message: "Please wait...", preferredStyle: .alert)
    alert.view.tintColor = UIColor.black
    let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 10,y: 5,width: 50, height: 50)) as UIActivityIndicatorView
    loadingIndicator.hidesWhenStopped = true
    loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
    loadingIndicator.startAnimating();

    alert.view.addSubview(loadingIndicator)
    self.present(alert, animated: true)

}

我用UIButton替换了函数的sender参数,并去掉了对主队列的Dispatch调用,因为这是不必要的。
当你说有延迟时,你是指只有当你单步执行代码时才有延迟吗?因为是的,如果你单步执行代码,警报视图不会在self.present(alert, animated: true)之后立即显示。你必须等到函数完成执行。但是“延迟”是肉眼看不到的。你试过不单步执行代码就运行上面的代码吗?

0s0u357o

0s0u357o4#

调整警报视图约束以设置UIActivityIndicatorView。

func presentLoader() {

        let alert = UIAlertController(title: nil, message: "", preferredStyle: .alert)
        let activityIndicator = UIActivityIndicatorView(style: .large)
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        activityIndicator.isUserInteractionEnabled = false
        activityIndicator.color = .blue
        activityIndicator.startAnimating()
                
        alert.view.addSubview(activityIndicator)
        
        NSLayoutConstraint.activate([
            alert.view.heightAnchor.constraint(equalToConstant: 95),
            alert.view.widthAnchor.constraint(equalToConstant: 95),
            activityIndicator.centerXAnchor.constraint(equalTo: alert.view.centerXAnchor),
            activityIndicator.centerYAnchor.constraint(equalTo: alert.view.centerYAnchor)
        ])
        
        present(alert, animated: true)
    }

结果:

相关问题