2

I am trying to add custom messages using Message Kit, and it's displaying as expected except my custom messages are getting stacked with other previous messages on top of each other as I add new messages, and when I scroll these messages keep switching place which is related to dequeue reusable cell.

Here is my collection view where the custom cell is returned:

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

    if isSectionReservedForTypingIndicator(indexPath.section) {
        return super.collectionView(collectionView, cellForItemAt: indexPath)
    }

    let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
    if case .custom = message.kind {
        let cell =  messagesCollectionView.dequeueReusableCell(withReuseIdentifier: "custom cell", for: indexPath) as! MyCustomCell
        cell.Chats = self
        cell.configure(with: message, at: indexPath, and: messagesCollectionView)
        return cell
    }

    return super.collectionView(collectionView, cellForItemAt: indexPath)
}

func numberOfItems(inSection section: Int, in messagesCollectionView: MessagesCollectionView) -> Int {
    return 1
}

MyCustomCell is the custom class used and it has a MessageSizeCalculator, below is the calculator size and the Flow:

open class CustomMessageSizeCalculator: MessageSizeCalculator {
    public override init(layout: MessagesCollectionViewFlowLayout? = nil) {
        super.init()
        self.layout = layout
    }

    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

        switch message.kind{
            case .custom(let item):
                let constuctedUIV = UIView(CGRect(x:0,y:0, height:100, width:100))

                return CGSize(width: maxWidth, height: constuctedUIV.frame.height + 30)
                break
            default:
                break;
        }

        return CGSize(width: ((maxWidth / 2) - inset), height: ((maxWidth / 4) - inset))
    }
}

open class MyCustomMessagesFlowLayout: MessagesCollectionViewFlowLayout {
    lazy open var customMessageSizeCalculator = CustomMessageSizeCalculator(layout: self)

    open override func cellSizeCalculatorForItem(at indexPath: IndexPath) -> CellSizeCalculator {
        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()
        superCalculators.append(customMessageSizeCalculator)
        return superCalculators
    }
}
Benjamin Buch
  • 4,752
  • 7
  • 28
  • 51
Camille Basbous
  • 299
  • 5
  • 11
  • 34
  • 1
    override prepare for reuse method for cell and reset your cell for next item. – Zain May 07 '23 at 19:44
  • I also tried your code on the message kit's examples, it looks fine with your layout and size calculators, I guess it has something todo with your cell class, can you post your cell's code, maybe remove the sensitive code. – kakaiikaka May 09 '23 at 00:23

0 Answers0