Swift中弹窗延迟显示问题:如何让函数F暂停至弹窗关闭?
问题解答:弹窗延迟显示&函数等待弹窗关闭
嘿,作为Swift新手碰到这个问题太正常啦,我来帮你拆解清楚~
为什么弹窗要等函数F执行完才显示?
iOS的UI操作都是在主线程的RunLoop里处理的。你在函数F里调用present(vc, animated: true)的时候,其实只是把「显示弹窗」这个任务加到了主线程的任务队列里,而当前函数F本身也是主线程上一个正在执行的任务。RunLoop的规则是:必须等当前正在执行的任务(也就是函数F)完全跑完,才会去处理队列里的下一个任务(弹窗显示)。所以就出现了弹窗要等F执行完才出来的情况。
要是你在F末尾加个print("F执行结束"),会发现这个打印先输出,然后弹窗才显示,就是这个道理~
怎么让函数F暂停,等弹窗关闭后再继续?
绝对不能用sleep()或者死循环这种方式阻塞主线程——那样会让整个APP卡死,用户体验崩了不说,iOS甚至可能直接杀掉你的进程。正确的做法是用异步回调,把弹窗关闭后的逻辑放到回调里,让代码「异步等待」而不是「阻塞等待」。
步骤1:给弹窗VC加回调闭包
先修改你的P2_Competition_Pop_UpViewController,给它加一个闭包属性,用来通知外部弹窗已经关闭:
class P2_Competition_Pop_Up: UIViewController { // 定义回调闭包,可选类型避免空值问题 var onDismiss: (() -> Void)? // 假设你有一个关闭弹窗的按钮,点击事件里触发回调 @IBAction func closeButtonTapped(_ sender: UIButton) { dismiss(animated: true) { // 弹窗完全关闭后,调用回调闭包 self.onDismiss?() } } // 如果是通过点击背景或者其他方式关闭弹窗,也要在dismiss的completion里触发onDismiss }
步骤2:重构函数F的逻辑
把原来函数F里弹窗之后的代码抽出来,放到一个新方法里,然后在弹窗的回调里调用这个方法:
func functionF() { // --- 函数F前面的业务代码 --- print("执行F的前半部分逻辑") // 弹窗相关代码 if let vc = storyboard?.instantiateViewController(withIdentifier: "P2CompetitionPopUpId") as? P2_Competition_Pop_Up { vc.modalPresentationStyle = .overCurrentContext // 设置弹窗关闭后的回调 vc.onDismiss = { [weak self] in // 弹窗关闭后,继续执行F剩下的逻辑 self?.continueAfterPopUp() } present(vc, animated: true, completion: nil) } else { print("error creating P2_Competion_Pop_Up") } // 注意:原来F里弹窗之后的代码,现在不要写在这里了! } // 弹窗关闭后执行的逻辑 private func continueAfterPopUp() { // --- 原来函数F里弹窗之后的业务代码 --- print("弹窗关闭了,继续执行F的后半部分逻辑") // 比如更新游戏状态、计算分数等等 }
这样一来,函数F执行到弹窗部分就会把后续逻辑交给回调,主线程能立刻处理弹窗显示,等用户关闭弹窗后,回调闭包触发,才会继续执行剩下的逻辑,完全符合你的需求~
内容的提问来源于stack exchange,提问作者ProfessorHelloKittyNr1
相关产品推荐
相关产品推荐

