Swift中实现UIBarButton单击显示Toast、双击执行返回页面功能
嘿,这个场景我之前也碰到过,核心难点就是要区分开单击和双击的触发逻辑,避免两种操作互相干扰。下面是我整理的完整可运行方案,直接就能套用:
第一步:准备全局变量(用于区分单击/双击)
在你的ViewController里先定义两个变量,用来控制定时器和标记双击状态:
var tapTimer: Timer? var didTriggerDoubleTap = false
第二步:创建带手势的导航栏按钮
因为UIBarButtonItem本身不是UIView,我们需要先创建一个自定义UIButton,再把它包装成UIBarButtonItem,这样才能添加双击手势:
override func viewDidLoad() { super.viewDidLoad() // 1. 创建自定义按钮 let actionButton = UIButton(type: .system) actionButton.setTitle("操作按钮", for: .normal) actionButton.titleLabel?.font = UIFont.systemFont(ofSize: 16) // 2. 添加单击事件(用Target-Action) actionButton.addTarget(self, action: #selector(onSingleTap), for: .touchUpInside) // 3. 添加双击手势识别器 let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(onDoubleTap)) doubleTapGesture.numberOfTapsRequired = 2 actionButton.addGestureRecognizer(doubleTapGesture) // 4. 把按钮包装成UIBarButtonItem,放到导航栏 navigationItem.rightBarButtonItem = UIBarButtonItem(customView: actionButton) }
第三步:实现单击/双击的逻辑处理
这里用定时器来延迟执行单击的Toast操作,如果在延迟期间触发了双击,就取消定时器,直接执行返回:
@objc private func onSingleTap() { // 重置双击标记 didTriggerDoubleTap = false // 延迟0.2秒执行Toast(时间可以根据交互手感调整) tapTimer?.invalidate() tapTimer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { [weak self] _ in guard let self = self, !self.didTriggerDoubleTap else { return } // 执行Toast显示 self.showToast() } } @objc private func onDoubleTap() { // 标记已经触发双击,取消单击的定时器 didTriggerDoubleTap = true tapTimer?.invalidate() // 执行页面返回操作 navigationController?.popViewController(animated: true) } // 基于你提供的Toast代码,补充了自动消失逻辑 private func showToast() { let toastLabel = UILabel(frame: CGRect(x: 20, y: view.frame.height - 100, width: 350, height: 35)) toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.6) toastLabel.textColor = .white toastLabel.textAlignment = .center toastLabel.font = UIFont.systemFont(ofSize: 14) toastLabel.text = "这是提示类Toast" toastLabel.layer.cornerRadius = toastLabel.frame.height / 2 toastLabel.clipsToBounds = true view.addSubview(toastLabel) // 添加淡入淡出动画,2秒后自动消失 UIView.animate(withDuration: 0.3) { toastLabel.alpha = 1.0 } completion: { _ in UIView.animate(withDuration: 0.3, delay: 2.0) { toastLabel.alpha = 0.0 } completion: { _ in toastLabel.removeFromSuperview() } } }
关键细节说明:
- 为什么用定时器?如果直接同时添加单击和双击手势,系统会优先触发单击,导致双击无法正常响应。用定时器延迟执行单击逻辑,就能在双击触发时及时取消单击操作。
- 必须用自定义UIButton:UIBarButtonItem本身不能直接添加手势识别器,所以要先创建按钮再包装成BarButtonItem。
- Toast部分保留了你原有的布局代码,补充了自动消失的动画,避免Toast一直停留在页面上影响交互。
内容的提问来源于stack exchange,提问作者Swift_prasad
相关产品推荐
相关产品推荐

