UIAlertAction 处理程序/闭包不执行

UIAlertAction handler/closure does not execute

提问人:cvld 提问时间:10/10/2022 更新时间:10/11/2022 访问量:95

问:

我有一个 UIViewController 扩展,我用它来在任何视图控制器中显示警报。它工作正常,直到这个奇怪的用例发生:

extension UIViewController {
    func showModal(title: String, msg: String, handler: ((UIAlertAction) -> Void)? = nil) {
        let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: handler))
        DispatchQueue.main.async {
            self.present(alert, animated: true, completion: nil)
        }
    }
}

在视图控制器中,我点击一个按钮,该按钮会触发网络获取:

@IBAction func didTapSave(_ sender: UIButton) {

Task {
    
    let result = await BalanceManager.shared.fetchAllBalances()
    
    switch result {
    case .success(_):
        self.showModal(title: "", msg: "account successfully saved") { (_) in
            //This code always gets executed
            self.navigationController?.popViewController(animated: true)
        }
    case .failure(let failure):
        self.showModal(title: "", msg: "failure") { (_) in
            //Code in here is not executed
            print("Failure closure")
        }
    }
}

我不明白为什么在“.failure”的情况下,showModal 的闭包不执行。 如果我使用 self.showModal 在行上设置断点,代码会到达那里,但当我点击弹出窗口上的“确定”时不会执行闭包

iOS Swift 闭包 UIAalertController

评论

0赞 Thang Phi 10/10/2022
你确定是因为?我想也许问题可能来自你的总是返回.UIAlertresultsuccess

答:

0赞 cvld 10/11/2022 #1

我想通了,这是我的编程错误和缺乏适当的睡眠:)。另一个正在侦听有关相同提取结果的通知的 VC 正在触发弹出窗口,即使 VC 不可见,但处于活动状态,嵌入在选项卡栏控制器中。所以我的“失败”弹出窗口从未正确执行。在我使用 sender 参数更新了 showModal 方法后,我想通了,然后我添加了一个修复程序,该修复程序要求调用 VC 在想要显示弹出窗口时可见:

func showModal(sender: UIViewController, title: String, msg: String, handler: ((UIAlertAction) -> Void)? = nil) {
    let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: handler))
    DispatchQueue.main.async {
      if sender.isVisible() {
        self.present(alert, animated: true, completion: nil)
      }
    }
  }

其中 isVisible():

extension UIViewController {
  func isVisible() -> Bool {
    return self.isViewLoaded && self.view.window != nil
  }
}