iOS中ActionSheet点击后重复弹出,首次无法跳转拨号问题排查
解决ActionSheet首次点击后需二次操作才能进入拨号界面的问题
问题根源
你遇到的问题核心是复用了同一个UIAlertController(即actionSheet)实例,但每次调用settingActionSheet时都会重复添加menu1和cancel两个Action。这导致ActionSheet内部堆积了多组重复的操作选项:
- 首次点击按钮弹出的ActionSheet里,你看到的拨号选项可能是之前残留的旧Action,而旧Action的逻辑因状态异常(比如
phoneNumberURL未正确初始化)没触发拨号; - 第二次点击时才真正触发到新添加的Action,因此能进入拨号界面。
解决方案
有两种常用修复方式,选其一即可:
方案1:每次创建新的ActionSheet实例(推荐)
不再复用全局的actionSheet,每次需要弹出时都创建新的UIAlertController,避免Action堆积:
// 修改为返回新的ActionSheet实例 private func createActionSheet(phoneNumber: String) -> UIAlertController { let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let image = UIImage(named: "tellephone9") let callAction = UIAlertAction(title: phoneNumber, style: .default) { _ in guard let phoneURL = self.phoneNumberURL else { return } if UIApplication.shared.canOpenURL(phoneURL) { UIApplication.shared.open(phoneURL) } } callAction.setValue(image?.withRenderingMode(.alwaysOriginal), forKey: "image") let cancelAction = UIAlertAction(title: "취소", style: .cancel) actionSheet.addAction(callAction) actionSheet.addAction(cancelAction) return actionSheet } @IBAction func searchPassword(_ sender: UIButton) { print(#function) // 替换为你的实际电话号码 let sheet = createActionSheet(phoneNumber: "目标号码") present(sheet, animated: true) }
方案2:复用实例但清空旧Action
如果坚持要复用全局的actionSheet,每次弹出前先清空所有已存在的Action,再添加新的:
private func setupActionSheet(phoneNumber: String) { // 关键:先清空所有旧Action actionSheet.removeAllActions() let image = UIImage(named: "tellephone9") let callAction = UIAlertAction(title: phoneNumber, style: .default) { _ in guard let phoneURL = self.phoneNumberURL else { return } if UIApplication.shared.canOpenURL(phoneURL) { UIApplication.shared.open(phoneURL) } } callAction.setValue(image?.withRenderingMode(.alwaysOriginal), forKey: "image") let cancelAction = UIAlertAction(title: "취소", style: .cancel) actionSheet.addAction(callAction) actionSheet.addAction(cancelAction) } @IBAction func searchPassword(_ sender: UIButton) { print(#function) // 先更新ActionSheet内容,再弹出 setupActionSheet(phoneNumber: "目标号码") present(actionSheet, animated: true) }
验证逻辑
修复后,每次弹出的ActionSheet都只有一组正确的拨号和取消选项,点击拨号选项时会直接触发openURL逻辑,无需二次点击。
内容的提问来源于stack exchange,提问作者eeuin
相关产品推荐
相关产品推荐

