I'm using JSQMesssagesViewController to build a messaging app. I can now send an image using this, but would like to tap the image to open in full screen. This functionality would be similar to the standard messaging application that allows you to tap on an image "bubble", and pinch to zoom in and out. Has anyone had experience doing this with JSQMessagesViewController? Thanks to those who who can lend assistance!
4 Answers
SWIFT 3: I found another way without using any other pods/libraries.
1) Add var selectedImage: UIImage?
on top of your ChatViewController
.
2) Override the method didTapMessageBubbleAt
, for example:
override func collectionView(_ collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAt indexPath: IndexPath!) {
if let test = self.getImage(indexPath: indexPath) {
selectedImage = test
self.performSegue(withIdentifier: "showMedia", sender: self)
}
}
3) Add this function to get the image when it's clicked on by the user and return an UIImage
(will return nil if it's a text message that has been taped on):
func getImage(indexPath: IndexPath) -> UIImage? {
let message = self.messages[indexPath.row]
if message.isMediaMessage == true {
let mediaItem = message.media
if mediaItem is JSQPhotoMediaItem {
let photoItem = mediaItem as! JSQPhotoMediaItem
if let test: UIImage = photoItem.image {
let image = test
return image
}
}
}
return nil
}
4) Add the segue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showMedia" {
if let pageDeDestination = segue.destination as? ShowMediaViewController {
pageDeDestination.image = selectedImage!
} else {
print("type destination not ok")
}
} else {
print("segue inexistant")
}
}
5) In the Interface Builder, add a View controller nearby your chatVC
and add a segue (type Show
) with showMedia
as the segue identifier. Add an image view in the new viewcontroller
.
6) Here is the code of my ShowMediaViewController
:
class ShowMediaViewController: UIViewController {
var image: UIImage? = nil
var titreText: String!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var titre: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
//titre.text = titreText
if image != nil {
imageView.image = image
} else {
print("image not found")
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Don't forget to put "Aspect Fit" as a parameter in your image view (in the interface builder) to display correctly the image.

- 5,488
- 10
- 51
- 76

- 129
- 1
- 6
JSQmessage does not handle that but you can add this functionality in this method and by using zoomPopup class:
- (void)collectionView:(JSQMessagesCollectionView *)collectionView didTapMessageBubbleAtIndexPath:(NSIndexPath *)indexPath
{
JSQMessage *message = [self.messageModelData.messages objectAtIndex:indexPath.row];
if (message.isMediaMessage) {
id<JSQMessageMediaData> mediaItem = message.media;
if ([mediaItem isKindOfClass:[JSQPhotoMediaItem class]]) {
NSLog(@"Tapped photo message bubble!");
JSQPhotoMediaItem *photoItem = (JSQPhotoMediaItem *)mediaItem;
[self popupImage:photoItem.image];
}
}
}
- (void) popupImage: (UIImage*)image
{
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *topView = window.rootViewController.view;
imageView = [[UIImageView alloc] initWithImage:image];
zoomPopup *popup = [[zoomPopup alloc] initWithMainview:topView andStartRect:CGRectMake(topView.frame.size.width/2, topView.frame.size.height/2, 0, 0)];
[popup showPopup:imageView];
}
and you can see zoomPopup here: https://github.com/Tintenklecks/zoomPopup

- 1,428
- 13
- 27
-
i am working on JSQMessageView Controller. Please look into this issue http://stackoverflow.com/q/38371995/2522603 – ChenSmile Jul 14 '16 at 11:14
Swift 3.0.1 Hope it helps someone.I have tested this code
I have used following code to show image
on Full Screen when tapped Image
on JSQMessagesViewController
.
override func collectionView(_ collectionView: JSQMessagesCollectionView, didTapMessageBubbleAt indexPath: IndexPath) {
let message: JSQMessage? = messages[indexPath.row]
if message?.isMediaMessage != nil {
let mediaItem: JSQMessageMediaData? = message?.media
if (mediaItem is JSQPhotoMediaItem) {
print("Tapped photo message bubble!")
let photoItem = mediaItem as? JSQPhotoMediaItem
let newImageView = UIImageView(image: photoItem?.image)
newImageView.frame = UIScreen.main.bounds
newImageView.backgroundColor = .gray
newImageView.contentMode = .scaleAspectFit
newImageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
newImageView.addGestureRecognizer(tap)
self.view.addSubview(newImageView)
self.tabBarController?.tabBar.isHidden = true // tabBarController exists
self.navigationController?.isNavigationBarHidden = true // default navigationController
}
}
}
func dismissFullscreenImage(_ sender: UITapGestureRecognizer) {
self.tabBarController?.tabBar.isHidden = false
self.navigationController?.isNavigationBarHidden = false
sender.view?.removeFromSuperview() // This will remove image from full screen
}

- 1,441
- 18
- 31
if using with PhotoSlider(https://github.com/nakajijapan/PhotoSlider)
// var images = [UIImage]() // puts images of messages here
override func collectionView(_ collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAt indexPath: IndexPath!) {
let index = indexPath.row
let message = messages[index]
if message.isMediaMessage {
if message.media.isKind(of: JSQPhotoMediaItem.self) {
let photoSlider = PhotoSlider.ViewController(images: images)
let i = images.index(of: (message.media as! JSQPhotoMediaItem).image)!
photoSlider.currentPage = i
photoSlider.modalPresentationStyle = .overCurrentContext
photoSlider.modalTransitionStyle = .crossDissolve
present(photoSlider, animated: true, completion: nil)
}
}
}

- 205
- 5
- 5