MessageKit消息气泡双击识别器添加问题:未识别选择器报错排查
解决MessageKit消息气泡双击手势的报错问题
嘿,我看你遇到的这个报错是典型的目标对象与方法归属不匹配的问题,还有手势添加的位置也不对,我来一步步帮你搞定:
先说说你代码里的两个核心问题
- 手势Target设置错误:你把手势的
target设成了messagesCollectionView,但你的doubleTap方法是写在当前ViewController里的啊!系统会去MessagesCollectionView实例里找这个方法,自然找不到,就抛出了unrecognized selector的错误。 - 手势添加的位置完全错了:
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
相关产品推荐
相关产品推荐

