1

我正在努力解决如何在聊天室中显示系统消息。目前,我已经在 Swift 中使用 MessageKit 构建了聊天室并完成了整体 UI。我想要的是,当我点击右上角的红色按钮时,聊天室会自动显示一条系统消息“按钮被点击”,如下图示例。如果有人可以提供帮助,非常感谢!

样本图片

4

1 回答 1

0

这个答案可能有点晚,但解决方案很简单。您需要做的就是创建一个自定义单元格并使用消息视图控制器数据源对其进行配置。

有一个综合指南,您可以在官方 repo 上获取有关如何与示例一起执行的帮助

这是一些演示代码(由于我引用了一些自定义 UIView 子类,您将无法复制和粘贴它)

首先,创建你的UICollectionViewCell

class SystemMessageCell: CollectionCell<MessageType> {
  lazy var messageText = Label()
    .variant(.regular(.small))
    .color(.gray)
    .align(.center)

  override func setupView() {
    addSubview(messageText)
  }

  override func setupConstraints() {
    messageText.snp.makeConstraints { $0.edges.equalToSuperview() }
  }

  override func update() {
    guard let item = item else { return }
    switch item.kind {
    case .custom(let kind):
      guard let kind = kind as? ChatMessageViewModel.Kind else { return }
      switch kind {
      case .system(let systemMessage):
        messageText.text = systemMessage
      }
    default:
      break
    }
  }
}

其次,您需要创建两个单独的文件。一个是尺寸计算器,另一个是自定义流程布局。

class SystemMessageSizeCalculator: MessageSizeCalculator {
  override func messageContainerSize(for message: MessageType) -> CGSize {
    // Just return a fixed height.
    return CGSize(width: UIScreen.main.bounds.width, height: 20)
  }
}
class SystemMessageFlowLayout: MessagesCollectionViewFlowLayout {
  lazy open var sizeCalculator = SystemMessageSizeCalculator(layout: self)

  override open func cellSizeCalculatorForItem(at indexPath: IndexPath) -> CellSizeCalculator {
    let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
    if case .custom = message.kind {
      return sizeCalculator
    }
    return super.cellSizeCalculatorForItem(at: indexPath);
  }
}

最后,将它全部连接到您的 MessagesViewController 中,如下所示:

class ChatViewController: MessagesViewController {

  override func viewDidLoad() {
    messagesCollectionView = MessagesCollectionView(frame: .zero, collectionViewLayout: SystemMessageFlowLayout())
    super.viewDidLoad()
    messagesCollectionView.register(SystemMessageCell.self)
  }

  // MARK: - Custom Cell

  override open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let messagesDataSource = messagesCollectionView.messagesDataSource else {
      fatalError("Ouch. nil data source for messages")
    }

    let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
    if case .custom = message.kind {
      let cell = messagesCollectionView.dequeueReusableCell(SystemMessageCell.self, for: indexPath)
      cell.item = message
      return cell
    }
    return super.collectionView(collectionView, cellForItemAt: indexPath)
  }
}

最终结果将是这样的:

示例截图

于 2020-06-27T14:18:34.157 回答