Search code examples
iosimageuiimagevieworientationmkannotationview

MKAnnotationView image orientation


I have a MKMapView in which I can have multiple ARDVenueAnnotationView (subclass of MKAnnotationView) with a custom image at same coordinates. Thus, these annotations overlap. What I have done for this, is to change the anchorPoint of the annotation view's layer. This is working as image below (4 centered annotations have the same coordinates) :

Besides, I would like the annotations to change their image orientation so the little image tail points to the coordinate (don't mind the annotations order) :

Here comes my issue, when I setImage: on my annotation view, constructing this image with + (UIImage *)imageWithCGImage:scale:orientation:, the orientation does not change. Here is my code that update the image :

- (void)updateImage
{
    UIImage *selectedImage = [UIImage imageNamed:@"redPin"];
    if (!self.isCluster && self.selected) {
        selectedImage = [UIImage imageNamed:@"whitePin"];
    }

    UIImageOrientation orientation;

    switch (self.anchorCorner) {
        case ARDVenueAnnotationAnchorCornerBottomLeft:
            orientation = UIImageOrientationUpMirrored;
        break;

        case ARDVenueAnnotationAnchorCornerTopLeft:
            orientation = UIImageOrientationDown;
        break;

        case ARDVenueAnnotationAnchorCornerTopRight:
            orientation = UIImageOrientationDownMirrored;
        break;

        default:
            orientation = UIImageOrientationUp;
        break;
    }
    UIImage *image = [[UIImage alloc] initWithCGImage:selectedImage.CGImage scale:selectedImage.scale orientation:orientation];
    [self setImage:image];
}

Where anchorCorner is the property to set when I want the annotation view to shift for the image little tail to points to the coordinates. This method never changes the image orientation (default image has the tail at bottom right) and it keeps rendering as first picture above.

When I add an UIImageView as subview of my annotation view, it shows the good image orientation (as shown in the second picture).

My questions :

Why setImage: does not consider the image orientation ? Or maybe I am doing something wrong...

How can I achieve this without adding UIImageView as subview ? after all, image property is here for a reason


Solution

  • Try creating an image with the original image with the code:

    static inline double radians (double degrees) {return degrees * M_PI/180;}
    -(UIImage*) image :(UIImage*) src withOrientation: (UIImageOrientation) orientation
    {
        UIGraphicsBeginImageContext(src.size);
    
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        if (orientation == UIImageOrientationRight) {
            CGContextRotateCTM (context, radians(90));
        } else if (orientation == UIImageOrientationLeft) {
            CGContextRotateCTM (context, radians(-90));
        } else if (orientation == UIImageOrientationDown) {
            // NOTHING
        } else if (orientation == UIImageOrientationUp) {
            CGContextRotateCTM (context, radians(90));
        }
    
        [src drawAtPoint:CGPointMake(0, 0)];
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }
    

    You may also need to flip the image so use this code:

    UIImage* flippedImage = [UIImage imageWithCGImage:image.CGImage 
                                                scale:image.scale
                                          orientation:UIImageOrientationUpMirrored];