4

I am trying to enlarge an image in the MessageCollectionView in a cell when it is tapped, something standard in most messaging apps. I successfully am able to recognize the user's tap on each cell and determine if it is a photo or a text cell, but my imageTapped function doesnt seem to be triggering. The img value I am passing to the imageTapped function inside the didTapMessage function and looks like it is a UIImageView as expected. The console print inside imageTapped doesn't seem to be triggering, so it never enters that function. Maybe I am missing something simple here, but I feel like it should be going thru that function!

I am using Swift 5, iOS 13.2, and MessageKit.

Code:

// MARK: - MessageCellDelegate
// With help from:
// - https://github.com/MessageKit/MessageKit/issues/778
// - https://stackoverflow.com/questions/45536405/full-screen-an-image-inside-a-tableviewcell-when-tapped-swift
// - https://github.com/MessageKit/MessageKit/issues/261
extension RoomVC: MessageCellDelegate {
    func didTapMessage(in cell: MessageCollectionViewCell) {
        guard let indexPath = messagesCollectionView.indexPath(for: cell) else { return }
        guard let messagesDataSource = messagesCollectionView.messagesDataSource else { return }
        let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
        switch message.kind {
            case .photo(let photoItem):
                log.info("Message is a photo.")
                if let img = photoItem.image{
                    self.imageTapped(image: img)
                }
            default:
                log.info("Message is not a photo.")
                break
        }
    }

    func imageTapped(image: UIImage){
        log.info("Entered the imageTapped function.")
        let newImageView = UIImageView(image: image)
        newImageView.frame = UIScreen.main.bounds
        newImageView.backgroundColor = .black
        newImageView.contentMode = .scaleAspectFit
        newImageView.isUserInteractionEnabled = true
        let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
        newImageView.addGestureRecognizer(tap)
        self.view.addSubview(newImageView)
        self.navigationController?.isNavigationBarHidden = true
        self.tabBarController?.tabBar.isHidden = true
    }

    @objc func dismissFullscreenImage(_ sender: UITapGestureRecognizer) {
        self.navigationController?.isNavigationBarHidden = false
        self.tabBarController?.tabBar.isHidden = false
        sender.view?.removeFromSuperview()
    }
}
douglasrcjames
  • 1,133
  • 3
  • 17
  • 37

3 Answers3

4

Not sure why I got downvoted for this question, but the solution we found was that we were passing the image in as nil to the url instead of image when we were grabbing the downloadUrl.

var kind: MessageKind {
        if let url = downloadURL {
            - return .photo(ImageMediaType(url: url, image: nil, placeholderImage: #imageLiteral(resourceName: "placeholder"), size: CGSize(width: 150, height: 150)))
            + return .photo(ImageMediaType(url: url, image: image, placeholderImage: #imageLiteral(resourceName: "placeholder"), size: CGSize(width: 150, height: 150)))
        }
        return .text(content)
    }
douglasrcjames
  • 1,133
  • 3
  • 17
  • 37
  • 1
    Thanks for creating this thread and posting the answer. I was also trying to figure out how implement the full screen image feature when tapped. Got it working now thanks to the snippets you posted. – fishhau Dec 10 '19 at 03:44
0

Solution is correct but I think it is missing implementation of func didTapImage. I was able to get it to work by implementing the same functionality in didTapImage instead of didTapMessage.

More details can be found here: https://github.com/MessageKit/MessageKit/blob/master/Example/Sources/View%20Controllers/ChatViewController.swift

line 195

0

Since the image is already loaded in the cell, I think you can save resources by getting the image object directly from the cell without finding the indexPath, the datasource, the message kind, etc...

func didTapImage(in cell: MessageCollectionViewCell) {
    if let image = (cell as? MediaMessageCell)?.imageView.image {
        // create and show the new ImageView with this image.
    }
}

You probably need to also hide the inputBar (just like you hide the tabBar):

self.messageInputBar.isHidden = true

and then show it again in your dismissFullScreenImage

self.messageInputBar.isHidden = false
Erwan
  • 3,733
  • 30
  • 25