You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MDC中无Storyboard实现UIBarButtonItem长按连调、单击单调?

实现UIBarButtonItem的单击/长按差异化调用(兼容MDC框架)

当然能搞定!我之前做视频播放器快进功能时就实现过类似逻辑,刚好适配你说的非Storyboard创建的UIBarButtonItem,而且完全兼容MDC框架。下面一步步给你讲怎么实现:

核心思路

因为UIBarButtonItem本身没法直接绑定手势,所以我们得先给它设置一个自定义的UIButton作为customView,然后给这个按钮同时添加单击事件和长按手势:

  • 单击时直接调用一次目标方法
  • 长按启动定时器,每隔固定时间重复调用目标方法,松开手就停止定时器

具体代码实现

1. 创建带自定义View的UIBarButtonItem

先创建一个UIButton,把它包装成UIBarButtonItem:

// 创建自定义按钮(如果用MDC的按钮组件也可以,比如MDCButton)
let actionButton = UIButton(type: .custom)
actionButton.setImage(UIImage(systemName: "forward.fill"), for: .normal)
actionButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44) // 导航栏标准尺寸
actionButton.addTarget(self, action: #selector(handleSingleTap), for: .touchUpInside)

// 包装成UIBarButtonItem
let barItem = UIBarButtonItem(customView: actionButton)
navigationItem.rightBarButtonItem = barItem

如果你的项目里用的是MDC的按钮组件(比如MDCButton),直接替换上面的UIButton就行,逻辑完全通用。

2. 添加长按手势与定时器逻辑

接下来给按钮绑定长按手势,并用定时器处理重复调用:

// 定义定时器变量,用来控制长按期间的重复调用
private var repeatTimer: Timer?

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 获取我们自定义的按钮
    guard let actionButton = navigationItem.rightBarButtonItem?.customView as? UIButton else { return }
    
    // 创建长按手势
    let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
    longPressGesture.minimumPressDuration = 0.3 // 长按触发的最短时间,可根据需求调整
    actionButton.addGestureRecognizer(longPressGesture)
}

// 长按手势的回调方法
@objc private func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
    switch gesture.state {
    case .began:
        // 长按开始,启动定时器,每隔0.1秒调用一次目标方法
        repeatTimer = Timer.scheduledTimer(
            timeInterval: 0.1,
            target: self,
            selector: #selector(performTargetAction),
            userInfo: nil,
            repeats: true
        )
    case .ended, .cancelled, .failed:
        // 长按结束/取消,停止并销毁定时器
        repeatTimer?.invalidate()
        repeatTimer = nil
    default:
        break
    }
}

// 单击事件的回调方法
@objc private func handleSingleTap() {
    // 单击时只调用一次目标方法
    performTargetAction()
}

// 你要执行的目标方法(比如快进/播放逻辑)
@objc private func performTargetAction() {
    // 这里写你的业务逻辑,比如:
    print("执行快进操作")
}

关键细节提醒

  • 手势冲突处理:不用担心单击和长按的冲突,系统会自动判断——按住时间超过minimumPressDuration就触发长按,快速松开就触发单击,完全不会互相干扰。
  • 定时器间隔调整:timeInterval参数可以按需修改,比如0.1秒是比较流畅的快进节奏,要是需要慢一点的重复频率,改成0.2秒就行。
  • MDC框架适配:这个方案和MDC框架完全兼容,不管你用的是MDC的导航栏还是按钮组件,只要能拿到UIBarButtonItem的customView,就能添加手势和事件逻辑。

内容的提问来源于stack exchange,提问作者czane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:13:26