Hi, first let me thank everyone for the amazing library !
I've been trying all day to make this work and couldn't so I'd like to know if anyone got UIContextMenuInteraction working with MessageKit ?
Heres what I tried to do and the errors I've encountered when I tried implementing it :
cellForItemAt I add the interaction to the cell :
Code sample
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAt: indexPath)
let menuInteraction = UIContextMenuInteraction.init(delegate: self)
cell.addInteraction(menuInteraction)
return cell
}
Errors:
messageContainerView.messageContainerView it simply doesn't work.UIContextMenuInteractionDelegate :
Code sample
extension ViewController: UIContextMenuInteractionDelegate {
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
guard let index = self.messagesCollectionView.indexPathForItem(at: location) else {
return nil
}
let message = self.messageForItem(at: index, in: self.messagesCollectionView)
let shareAction = UIAction.init(title: "Share",
image: nil,
identifier: UIAction.Identifier.init("msg.share"),
discoverabilityTitle: nil,
attributes: [],
state: .off) { (_) in
print("Share message here")
}
let menu = UIMenu.init(title: "",
image: nil,
identifier: .share,
options: .displayInline,
children: [copyAction])
let actionProvider: UIContextMenuActionProvider = { [weak self] (_) -> UIMenu? in
return menu
}
return UIContextMenuConfiguration.init(identifier: "msg.share" as NSCopying, previewProvider: nil, actionProvider: actionProvider)
}
}
Error:
indexPathForItem(at:) doesn't seem to return the correct index so I can't get the message content to use in UIActionHey @the0neyouseek ! You can use some methods from UICollectionViewDelegate for this. Add something like this to your MessagesViewController subclass:
func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
let message = messageList[indexPath.section] // Use whatever your backing store for messages is, in the example app its an array called messageList
return UIContextMenuConfiguration(identifier: message.messageId as NSCopying, previewProvider: nil) { suggestedActions in
// Create an action
let share = UIAction(title: "Share", image: nil) { action in
print("Sharing")
}
return UIMenu(title: "", children: [share])
}
}
func collectionView(_ collectionView: UICollectionView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
guard let identifier = configuration.identifier as? String,
let section = messageList.firstIndex(where: { $0.messageId == identifier }),
let cell = collectionView.cellForItem(at: IndexPath(row: 0, section: section)) as? MessageContentCell else {
return nil
}
let parameters = UIPreviewParameters()
parameters.backgroundColor = cell.messageContainerView.backgroundColor
return UITargetedPreview(view: cell.messageContainerView, parameters: parameters)
}
This creates UITargetedPreview using the cell's messageContainerView so you won't get the entire cell in your preview. Plus you don't have to override any methods or adding UIActions to your cells or anything 馃槉
Thanks for the help @kinoroy !
I should have thought there would already be a method somewhere, it works now 馃憤
Ps. If I may add something, I also had to set the visiblePath for the cell rounded corners to work:
let parameters = UIPreviewParameters()
parameters.backgroundColor = cell.messageContainerView.backgroundColor
+ parameters.visiblePath = UIBezierPath.init(roundedRect: cell.messageContainerView.bounds, cornerRadius: 16)
Most helpful comment
Hey @the0neyouseek ! You can use some methods from
UICollectionViewDelegatefor this. Add something like this to your MessagesViewController subclass:This creates UITargetedPreview using the cell's messageContainerView so you won't get the entire cell in your preview. Plus you don't have to override any methods or adding UIActions to your cells or anything 馃槉