iOS: How To Create A Resized Image MKAnnotationView

This week, I’ve been working on an app which, as part of it’s functionality, displayed nearby photos from Flickr on a map (see screenshot below).

Since I got the images from Flickr, I didn’t have control of the size of the photo returned. I also actually wanted them to be bigger, so I could also show the photos as a slideshow (which you get to by clicking the SlideShow button).

However, while the MKAnnotationView has an image property, it’s not possible to resize these images. So to get the images to show up resized, I had to subclass MKAnnotationView, add an image view subview of a small size to it, and then display the image in the image view:

//  FlickrImageAnnotationView.h

#import <MapKit/MapKit.h>

@interface FlickrImageAnnotationView : MKAnnotationView

@end
//  FlickrImageAnnotationView.m

#import "FlickrImageAnnotationView.h"

@interface FlickrImageAnnotationView()
{
    UIImageView *_imageView;
}

@end

@implementation FlickrImageAnnotationView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // make sure the x and y of the CGRect are half it's
        // width and height, so the callout shows when user clicks
        // in the middle of the image
        CGRect  viewRect = CGRectMake(-20, -20, 40, 40);
        UIImageView* imageView = [[UIImageView alloc] initWithFrame:viewRect];

        // keeps the image dimensions correct
        // so if you have a rectangle image, it will show up as a rectangle,
        // instead of being resized into a square
        imageView.contentMode = UIViewContentModeScaleAspectFit;

        _imageView = imageView;

        [self addSubview:imageView];
    }
    return self;
}

- (void)setImage:(UIImage *)image
{
    // when an image is set for the annotation view,
    // it actually adds the image to the image view
    _imageView.image = image;
}

@end

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.

  • poom

    Hi Natasha,

    If you have some time, I would love to hear some advice from you.

    I know you completed Dev Bootcamp since I have been reading your blog for a while.

    I know a fair amount of iOS coding, and even though I am a beginner coder, I
    I would love to create an MVP of an iOS app so I was thinking of applying to a RoR bootcamp (not necessarily Dev Bootcamp) but do they teach you how to build scalable back-end infrastructure for a mobile-app?

    If not, do they teach you enough so that you could relatively easily learn how to build a back-end infrastructure using AWS for example?

    Thanks a lot!

    • Hi Poom,

      Feel free to email me at natasha at natashatherobot.com. Unfortunately, the bootcamps are more of an introduction to programming. They teach you enough to get your career started, but a lot of it you’ll learn on the job.

      There’s more than enough to cover in 8-10 weeks, and on the things you learn is good software design patters, which will help you build a scalable back-end infrastructure, but there isn’t anything that focuses just on that. In RoR bootcamps, you usually deploy using Heroku, so they don’t teach you AWS, but I’m sure you can figure it out.

  • arax

    smrt
    i liek

  • Jignesh Patel

    I have 3 different size of images, How can I supply image size?

    • You can create the Image object first, then create the UIImageView based on the dimensions of the image – especially the height and width. Setting the ImageView’s contentMode to UIViewContentModeScaleAspectFit should rescale everything correctly though.

  • Ajay Singh Thakur

    i am unable to implement above in swift

    • Герман

      var imageView: UIImageView!

      override var image: UIImage? {
      set {
      imageView.image = newValue
      }
      get {
      return imageView.image
      }
      }

      override init(annotation: MKAnnotation?, reuseIdentifier: String?) {

      super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
      }

      override init(frame: CGRect) {

      let screenSize: CGRect = UIScreen.mainScreen().bounds
      let viewRect = CGRectMake(-20, -20, screenSize.height * 0.125, screenSize.width * 0.125)

      imageView = UIImageView(frame: viewRect)

      imageView.contentMode = .ScaleAspectFit

      super.init(frame: frame)
      self.addSubview(imageView)
      }

      required init?(coder aDecoder: NSCoder) {
      fatalError(“init(coder:) has not been implemented”)
      }

      • Герман

        Not sure about image get. May be at has to return super.image

  • Герман

    It helped me a lot! How to override the default mkannotaion behavior “show bubble on tap” with image taking the whole screen? Thanks