iOS如何点击Alert Controller弹窗内部关闭弹窗?
实现点击UIAlertController内部关闭弹窗+超时自动关闭(原生iOS)
我之前也碰到过一模一样的需求——不想等弹窗超时才关闭,点击弹窗内部任意区域就能关掉它,同时还要保留原来的3秒自动关闭功能,而且全程只用原生iOS代码实现,不用第三方类Toast的库。下面是我整理的完整解决方案:
核心思路
给UIAlertController的视图添加一个点击手势识别器,用户点击弹窗内部时触发关闭逻辑;同时保留你原本实现的3秒延迟自动关闭功能,两者互不冲突,还能互相兼容。
完整代码实现
class ViewController: UIViewController { let alertController = UIAlertController(title: "Alert", message: "SO Awesome!", preferredStyle: .alert) @IBOutlet var alertButton: UIButton! @IBAction func displayAlert(_ sender: UIButton) { self.present(alertController, animated: true, completion: { // 1. 添加点击弹窗内部关闭的手势 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissAlert)) // 允许手势穿透,避免影响弹窗内部其他交互(比如后续添加的按钮) tapGesture.cancelsTouchesInView = false self.alertController.view.addGestureRecognizer(tapGesture) // 2. 保留3秒自动关闭的逻辑 self.perform(#selector(self.dismissAlert), with: self.alertController, afterDelay: 3) }) } // 统一的弹窗关闭方法 @objc func dismissAlert(_ alert: UIAlertController? = nil) { let targetAlert = alert ?? self.alertController targetAlert.dismiss(animated: true, completion: nil) // 手动关闭后取消延迟任务,避免重复执行关闭操作 NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(self.dismissAlert), object: targetAlert) } override func viewDidLoad() { super.viewDidLoad() } }
关键细节说明
- 手势添加时机:必须在
present的completion闭包里添加手势,因为此时弹窗的视图已经被正确加载到视图层级中,手势才能正常响应。 - 手势穿透设置:
tapGesture.cancelsTouchesInView = false可以确保如果弹窗里有自定义按钮(比如确认、取消按钮),点击按钮时不会被这个全局手势拦截,按钮的正常交互依然有效。 - 取消延迟任务:手动关闭弹窗时,调用
NSObject.cancelPreviousPerformRequests取消之前的延迟关闭任务,避免弹窗已经被手动关闭后,还触发自动关闭逻辑导致不必要的错误。
这样就能同时满足点击弹窗内部关闭和超时自动关闭的需求,完全用原生代码实现,不需要依赖任何第三方库。
内容的提问来源于stack exchange,提问作者ByteSlinger
相关产品推荐
相关产品推荐

