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

MessageKit消息气泡双击识别器添加问题:未识别选择器报错排查

解决MessageKit消息气泡双击手势的报错问题

嘿,我看你遇到的这个报错是典型的目标对象与方法归属不匹配的问题,还有手势添加的位置也不对,我来一步步帮你搞定:

先说说你代码里的两个核心问题

  1. 手势Target设置错误:你把手势的target设成了messagesCollectionView,但你的doubleTap方法是写在当前ViewController里的啊!系统会去MessagesCollectionView实例里找这个方法,自然找不到,就抛出了unrecognized selector的错误。
  2. 手势添加的位置完全错了:messageStyle方法是用来返回消息气泡样式的,它会为每一条消息调用一次,你在这里给整个view加手势,不仅会重复添加N个相同手势,而且是给整个页面加,不是给单个消息气泡加,完全不符合你要双击气泡的需求。

正确的实现步骤

1. 保留你的双击方法,但优化逻辑精准性

先把你的doubleTap方法修改一下,让它能识别是哪个消息气泡被点击了:

@objc func doubleTap(gesture: UITapGestureRecognizer) {
    // 先判断手势触发的视图是不是消息气泡的容器视图
    guard let messageContainer = gesture.view as? MessageContainerView else { return }
    // 通过容器视图找到对应的cell
    guard let cell = messageContainer.superview?.superview as? MessagesCollectionViewCell else { return }
    // 获取cell对应的indexPath,进而拿到对应的消息数据
    if let indexPath = messagesCollectionView.indexPath(for: cell) {
        let tappedMessage = messages[indexPath.section] // 这里假设你的消息数组叫messages,根据实际情况修改
        print("双击了消息: \(tappedMessage.content)")
        // 在这里添加你双击后的业务逻辑,比如点赞、显示菜单等等
    }
    print("double tap called")
}

2. 在消息Cell创建时添加双击手势

我们需要在messagesCollectionView(_:cellForItemAt:)方法里,给每个消息的气泡容器添加手势,同时避免重复添加:

override func messagesCollectionView(_ messagesCollectionView: MessagesCollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    // 先调用父类方法获取默认的消息Cell
    let cell = super.messagesCollectionView(messagesCollectionView, cellForItemAt: indexPath) as! MessagesCollectionViewCell
    
    // 先移除cell上已有的双击手势,避免重复添加导致多次触发
    cell.messageContainerView.gestureRecognizers?.forEach { recognizer in
        if let tapRecognizer = recognizer as? UITapGestureRecognizer, tapRecognizer.numberOfTapsRequired == 2 {
            cell.messageContainerView.removeGestureRecognizer(tapRecognizer)
        }
    }
    
    // 创建并添加双击手势,注意target要设为self(当前ViewController)
    let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(doubleTap(gesture:)))
    doubleTapGesture.numberOfTapsRequired = 2
    // 把手势加到消息气泡的容器视图上,确保只有点击气泡才会触发
    cell.messageContainerView.addGestureRecognizer(doubleTapGesture)
    
    return cell
}

3. 删掉错误的手势添加代码

把你原来在messageStyle方法里添加手势的代码全部删掉,让这个方法只负责返回消息样式:

func messageStyle(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageStyle {
    let sender = message.sender
    if sender.senderId == selfSenderEmail?.senderId {
        // 自己发送的消息
        return .bubbleTailOutline(.blue, .bottomRight, .curved)
    }
    // 群聊消息颜色编码的更多判断语句
    return .bubbleTailOutline(.darkGray, .bottomLeft, .curved)
}

为什么这样改?

  • 把手势加到cell.messageContainerView上,确保只有点击消息气泡的区域才会触发双击,不会误触cell的空白部分。
  • 在Cell创建时添加手势,并且先清理旧的手势,避免重复添加导致一次双击触发多次方法。
  • Target设为self,因为doubleTap方法属于当前ViewController,系统能正确找到这个方法,不会再报找不到选择器的错误。

这样修改后,你双击消息气泡就能正常触发doubleTap方法啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:23:15