Hi ! I want to delete message by long press gesture on cell.
Currently i can copy the message, how can i implement the possibility of add one action ?
Thanks
@JulienLevallois You should be able to make Delete an action here by overriding
https://github.com/MessageKit/MessageKit/blob/0ceeb4905a20da59aac69d3468007e36df2b44ec/Sources/Controllers/MessagesViewController.swift#L246
Then implement it here:
https://github.com/MessageKit/MessageKit/blob/0ceeb4905a20da59aac69d3468007e36df2b44ec/Sources/Controllers/MessagesViewController.swift#L250
I dont understand where i need to override this, and what i need to do, to have 2 buttons, copy & delete
I dont understand where i need to override this, and what i need to do, to have 2 buttons, copy & delete
In the subclass of MessagesViewController, for example for the "delete" action (pseudocode out of my head):
class MyChatViewController: MessagesViewController {
override func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
if action == #selector(UIResponderStandardEditActions.delete(_:)) {
return true
}
return super.canPerformAction(action, withSender: sender)
}
override func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) {
// Delete action should be handled by yourself
if action == #selector(UIResponderStandardEditActions.delete(_:)) {
// Remove entry from datasource
// Delete section of the collectionView
return
}
// Use default handler instead
super.collectionView(collectionView, performAction: action, forItemAt: indexPath, withSender: sender)
}
}
Okay, forget my previous comment. I just tested it and it does not seem to work. I will try to get it working (as I also need custom actions) and report back :)
Okay, so @JulienLevallois here is a working example.
You need to
1.) implement the canPerformAction and performAction delegate methods in your subclass of MessagesViewController, like so:
override func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
if action == NSSelectorFromString("delete:") {
return true
} else {
return super.collectionView(collectionView, canPerformAction: action, forItemAt: indexPath, withSender: sender)
}
}
override func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) {
if action == NSSelectorFromString("delete:") {
// 1.) Remove from datasource
// insert your code here
// 2.) Delete sections
collectionView.deleteSections([indexPath.section])
} else {
super.collectionView(collectionView, performAction: action, forItemAt: indexPath, withSender: sender)
}
}
2.) Also you need to write an extension to the class of the UICollectionView subclass you are using and provide the implementation of the action there, e.g.
extension MessageCollectionViewCell {
override open func delete(_ sender: Any?) {
// Get the collectionView
if let collectionView = self.superview as? UICollectionView {
// Get indexPath
if let indexPath = collectionView.indexPath(for: self) {
// Trigger action
collectionView.delegate?.collectionView?(collectionView, performAction: NSSelectorFromString("delete:"), forItemAt: indexPath, withSender: sender)
}
}
}
}
That is the easiest way that I have found, I hope it helps!
Update: The code above is meant for system actions like copy or delete. In order to add custom actions, just follow the same scheme, but add your custom actions also to the UIMenuController, like so:
class CustomChatViewController: MessagesViewController {
override func viewDidLoad() {
super.viewDidLoad()
let customMenuItem = UIMenuItem(title: "Quote", action: #selector(MessageCollectionViewCell.quote(_:)))
UIMenuController.shared.menuItems = [customMenuItem]
}
}
Of course add the custom actions also to canPerformAction and performAction and to your UICollectionViewCell extension:
extension MessageCollectionViewCell {
@objc func quote(_ sender: Any?) {
// Get the collectionView
if let collectionView = self.superview as? UICollectionView {
// Get indexPath
if let indexPath = collectionView.indexPath(for: self) {
// Trigger action
collectionView.delegate?.collectionView?(collectionView, performAction: #selector(MessageCollectionViewCell.quote(_:)), forItemAt: indexPath, withSender: sender)
}
}
}
}
This issue has been marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
@Luke47 thank you very much :)
@JulienLevallois you need to delete the message from your datasource as he commented in the code.
Sent with GitHawk
Glad this one could be resolved! Thanks everyone 馃槂
Sent with GitHawk
Hi @Luke47 & @SD10 , " delete " messages dont works for Location type message. For text & images its good but long press dont works for location :/ I want to be able to delete a location message.
Do you have ideas why ?
Thanks
@kpsdeveloper You'll have to look at my comment above in this thread. This is a general iOS question and not really related to MessageKit 馃槩
@Luke47 I tried your answer, but my i couldn't get my delete action to do anything, not even a print statement. in other words, the delete action isn't called but it shows with the copy. any idea what might be wrong?
Okay this works, the issue i have with this now is in this func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType {
return messageList[indexPath.section]
} throws an index out of range error. How can I fix this please?
@tobitech Have you forgotten to call delete on the index path of the collection view while also removing it from your messages array?
Sent with GitHawk
@nathantannar4 I did
messageList.remove(at: indexPath.section)
collectionView.deleteSections([indexPath.section])
messagesCollectionView.reloadData()
the crash only occurs when i'm deleting the last item in my messages array
Hi, solution Luke gave seems like for deleting message from both sides. I need to implement deleting for only user who deletes it. So other person can still see the message like in whatsapp.
What changes should i make, as person leaves chat room and comes back this message will load again as its not deleted from database right? I need to implement a filtering method. Don't know how.
Most helpful comment
Okay, so @JulienLevallois here is a working example.
You need to
1.) implement the
canPerformActionandperformActiondelegate methods in your subclass ofMessagesViewController, like so:2.) Also you need to write an extension to the class of the
UICollectionViewsubclass you are using and provide the implementation of the action there, e.g.That is the easiest way that I have found, I hope it helps!
Update: The code above is meant for system actions like copy or delete. In order to add custom actions, just follow the same scheme, but add your custom actions also to the UIMenuController, like so:
Of course add the custom actions also to
canPerformActionandperformActionand to your UICollectionViewCell extension: