From 528cc8197c7b09ae67c71cfa20eac38781908fd1 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 18 Aug 2019 23:05:23 -0400 Subject: [PATCH] Add custom cell guide. --- CUSTOM_CELLS.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 CUSTOM_CELLS.md diff --git a/CUSTOM_CELLS.md b/CUSTOM_CELLS.md new file mode 100644 index 00000000..d74c39ab --- /dev/null +++ b/CUSTOM_CELLS.md @@ -0,0 +1,76 @@ +# MessageKit Custom Cell Guide(s) + +- [How can I add a custom cell?](#how-can-i-add-a-custom-cell) + +## How can I add a custom cell? + +**Note:** If you choose to use the `.custom` kind you are responsible for all of the cell's layout. Any `UICollectionViewCell` can be returned for custom cells which means any of the styling you provide from the `MessageDisplayDelegate` will not effect your custom cell. Even if you subclass your cell from `MessageContentCell`. + +Creating a custom cell involves four parts. First, you will need to create your custom cell so that it inherits from `UICollectionViewCell`. Second, you will need to set the size of your custom cell by creating a class that inherits from `MessageSizeCalculator`. Third, you will need to add your custom message size calculator to a class you make that inherits from `MessagesCollectionViewFlowLayout`. Fourth, you will need to register your custom cell and reference your custom collection view flow layout. + +### Example + +Let's take a look at what it takes to create a custom cell that displays a red block for your custom message. + +- **1. Custom Cell**: We create a cell that inherits from `UICollectionViewCell` +**MyCustomCell.swift** +``` +open class MyCustomCell: UICollectionViewCell { + open func configure(with message: MessageType, at indexPath: IndexPath, and messagesCollectionView: MessagesCollectionView) { + self.contentView.backgroundColor = UIColor.red + } +} +``` + +- **2. MessageSizeCalculator**: We set the size of our cell by creating a class that inherits from `MessageSizeCalculator` +**CustomMessageSizeCalculator.swift** +``` +open class CustomMessageSizeCalculator: MessageSizeCalculator { + open override func messageContainerSize(for message: MessageType) -> CGSize { + //HERE - Customize to size your content appropriately. This just returns a constant size. + return CGSize(width: 300, height: 130) + } +} +``` + +- **3. MessageFlowLayout**: We add our custom message size calculator to our collection view layout by creating a class that inherits from `MessagesCollectionViewFlowLayout` +**MyCustomMessagesFlowLayout.swift** +``` +open class MyCustomMessagesFlowLayout: MessagesCollectionViewFlowLayout { + lazy open var customMessageSizeCalculator = CustomMessageSizeCalculator(layout: self) + + override open 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); + } +} +``` +- **4. Implementation**: We register our custom cell and reference our newly created `MyCustomMessagesFlowLayout.swift` +**ConversationViewController.swift** +``` +internal class ConversationViewController: MessagesViewController { + override func viewDidLoad() { + super.viewDidLoad() + messagesCollectionView = MessagesCollectionView(frame: .zero, collectionViewLayout: MyCustomMessagesFlowLayout()) + messagesCollectionView.register(MyCustomCell.self) + //... + } +//... + 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(MyCustomCell.self, for: indexPath) + cell.configure(with: message, at: indexPath, and: messagesCollectionView) + return cell + } + return super.collectionView(collectionView, cellForItemAt: indexPath) + } +} +```