MessageKit 中的自定义单元格
Custom cell in MessageKit
我正在尝试在 MessageKit 中为 gif 添加自定义单元格,我想要与 MediaMessageCell
相同,唯一不同的是 UIImageView
替换为 GPHMediaView
,我扩展了MessageContentCell
并创建了一个 CustomClass。
CustomChatCell.swift
open class CustomChatCell: MessageContentCell {
/// The image view display the media content.
open var imageView: GPHMediaView = {
let imageView = GPHMediaView()
imageView.contentMode = .scaleAspectFill
return imageView
}()
// MARK: - Methods
/// Responsible for setting up the constraints of the cell's subviews.
open func setupConstraints() {
imageView.fillSuperview()
}
open override func setupSubviews() {
super.setupSubviews()
messageContainerView.addSubview(imageView)
setupConstraints()
}
open override func prepareForReuse() {
super.prepareForReuse()
self.imageView.image = nil
}
open override func configure(with message: MessageType, at indexPath: IndexPath, and messagesCollectionView: MessagesCollectionView) {
super.configure(with: message, at: indexPath, and: messagesCollectionView)
guard let displayDelegate = messagesCollectionView.messagesDisplayDelegate else {
fatalError("MessagesDisplayDelegate has not been set.")
}
switch message.kind {
case .custom(let mediaItem):
guard let media = mediaItem as? GPHMedia else { return }
imageView.media = media
default:
break
}
displayDelegate.configureMediaMessageImageView(imageView, for: message, at: indexPath, in: messagesCollectionView)
}
/// Handle tap gesture on contentView and its subviews.
open override func handleTapGesture(_ gesture: UIGestureRecognizer) {
let touchLocation = gesture.location(in: imageView)
guard imageView.frame.contains(touchLocation) else {
super.handleTapGesture(gesture)
return
}
delegate?.didTapImage(in: self)
}
}
CustomMessagesFlowLayout
和 CustomMessageSizeCalculator
open class CustomMessagesFlowLayout: MessagesCollectionViewFlowLayout {
open lazy var customMessageSizeCalculator = CustomMessageSizeCalculator(layout: self)
open override func cellSizeCalculatorForItem(at indexPath: IndexPath) -> CellSizeCalculator {
if isSectionReservedForTypingIndicator(indexPath.section) {
return typingIndicatorSizeCalculator
}
let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
if case .custom = message.kind {
return customMessageSizeCalculator
}
return super.cellSizeCalculatorForItem(at: indexPath)
}
open override func messageSizeCalculators() -> [MessageSizeCalculator] {
var superCalculators = super.messageSizeCalculators()
// Append any of your custom `MessageSizeCalculator` if you wish for the convenience
// functions to work such as `setMessageIncoming...` or `setMessageOutgoing...`
superCalculators.append(customMessageSizeCalculator)
return superCalculators
}
}
open class CustomMessageSizeCalculator: MessageSizeCalculator {
public override init(layout: MessagesCollectionViewFlowLayout? = nil) {
super.init()
self.layout = layout
}
open override func sizeForItem(at indexPath: IndexPath) -> CGSize {
guard let layout = layout else { return .zero }
let collectionViewWidth = layout.collectionView?.bounds.width ?? 0
let contentInset = layout.collectionView?.contentInset ?? .zero
let inset = layout.sectionInset.left + layout.sectionInset.right + contentInset.left + contentInset.right
return CGSize(width: ((collectionViewWidth / 2) - inset), height: ((collectionViewWidth / 2) - inset))
}
}
giphy
的视图不存在, avatarView
也不在中间,帮助解决这个问题,需要与光电池相同。
尝试替换整个方法
open override func sizeForItem(at indexPath: IndexPath) -> CGSize {
使用以下方法
open override func messageContainerSize(for message: MessageType) -> CGSize {
guard let layout = layout else { return .zero }
let maxWidth = messageContainerMaxWidth(for: message)
let contentInset = layout.collectionView?.contentInset ?? .zero
let inset = layout.sectionInset.left + layout.sectionInset.right + contentInset.left + contentInset.right
return CGSize(width: ((maxWidth / 2) - inset), height: ((maxWidth / 2) - inset))
}
我正在尝试在 MessageKit 中为 gif 添加自定义单元格,我想要与 MediaMessageCell
相同,唯一不同的是 UIImageView
替换为 GPHMediaView
,我扩展了MessageContentCell
并创建了一个 CustomClass。
CustomChatCell.swift
open class CustomChatCell: MessageContentCell {
/// The image view display the media content.
open var imageView: GPHMediaView = {
let imageView = GPHMediaView()
imageView.contentMode = .scaleAspectFill
return imageView
}()
// MARK: - Methods
/// Responsible for setting up the constraints of the cell's subviews.
open func setupConstraints() {
imageView.fillSuperview()
}
open override func setupSubviews() {
super.setupSubviews()
messageContainerView.addSubview(imageView)
setupConstraints()
}
open override func prepareForReuse() {
super.prepareForReuse()
self.imageView.image = nil
}
open override func configure(with message: MessageType, at indexPath: IndexPath, and messagesCollectionView: MessagesCollectionView) {
super.configure(with: message, at: indexPath, and: messagesCollectionView)
guard let displayDelegate = messagesCollectionView.messagesDisplayDelegate else {
fatalError("MessagesDisplayDelegate has not been set.")
}
switch message.kind {
case .custom(let mediaItem):
guard let media = mediaItem as? GPHMedia else { return }
imageView.media = media
default:
break
}
displayDelegate.configureMediaMessageImageView(imageView, for: message, at: indexPath, in: messagesCollectionView)
}
/// Handle tap gesture on contentView and its subviews.
open override func handleTapGesture(_ gesture: UIGestureRecognizer) {
let touchLocation = gesture.location(in: imageView)
guard imageView.frame.contains(touchLocation) else {
super.handleTapGesture(gesture)
return
}
delegate?.didTapImage(in: self)
}
}
CustomMessagesFlowLayout
和 CustomMessageSizeCalculator
open class CustomMessagesFlowLayout: MessagesCollectionViewFlowLayout {
open lazy var customMessageSizeCalculator = CustomMessageSizeCalculator(layout: self)
open override func cellSizeCalculatorForItem(at indexPath: IndexPath) -> CellSizeCalculator {
if isSectionReservedForTypingIndicator(indexPath.section) {
return typingIndicatorSizeCalculator
}
let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
if case .custom = message.kind {
return customMessageSizeCalculator
}
return super.cellSizeCalculatorForItem(at: indexPath)
}
open override func messageSizeCalculators() -> [MessageSizeCalculator] {
var superCalculators = super.messageSizeCalculators()
// Append any of your custom `MessageSizeCalculator` if you wish for the convenience
// functions to work such as `setMessageIncoming...` or `setMessageOutgoing...`
superCalculators.append(customMessageSizeCalculator)
return superCalculators
}
}
open class CustomMessageSizeCalculator: MessageSizeCalculator {
public override init(layout: MessagesCollectionViewFlowLayout? = nil) {
super.init()
self.layout = layout
}
open override func sizeForItem(at indexPath: IndexPath) -> CGSize {
guard let layout = layout else { return .zero }
let collectionViewWidth = layout.collectionView?.bounds.width ?? 0
let contentInset = layout.collectionView?.contentInset ?? .zero
let inset = layout.sectionInset.left + layout.sectionInset.right + contentInset.left + contentInset.right
return CGSize(width: ((collectionViewWidth / 2) - inset), height: ((collectionViewWidth / 2) - inset))
}
}
giphy
的视图不存在, avatarView
也不在中间,帮助解决这个问题,需要与光电池相同。
尝试替换整个方法
open override func sizeForItem(at indexPath: IndexPath) -> CGSize {
使用以下方法
open override func messageContainerSize(for message: MessageType) -> CGSize {
guard let layout = layout else { return .zero }
let maxWidth = messageContainerMaxWidth(for: message)
let contentInset = layout.collectionView?.contentInset ?? .zero
let inset = layout.sectionInset.left + layout.sectionInset.right + contentInset.left + contentInset.right
return CGSize(width: ((maxWidth / 2) - inset), height: ((maxWidth / 2) - inset))
}