Animated gif not working in MKMapView overlay using MKOverlayRenderer
Asked Answered
V

2

8

I am trying to display an animated gif in an overlay for MKMapView. The overlay is created using the MKOverlayRenderer. To animate the gif in iOS 7, I'm using the UIImage+animatedGIF category posted here on GitHub.

The image of the animated gif displays fine in the overlay using the category; however, the gif does not animate. I have no problem using the category to animate a gif in a UIImageView but it does not seem to work correctly in a map view overlay.

How can I use this category to place an animated gif in a map view overlay?

or...

Is there a way to place a UIImageView in the overlay which might solve my problem by setting the UIImageView with the animated gif?

My overlay renderer subclass is the following:

MapOverlayRenderer.h

#import <MapKit/MapKit.h>

@interface MapOverlayRenderer : MKOverlayRenderer
- (instancetype)initWithOverlay:(id<MKOverlay>)overlay overlayImage:(UIImage *)overlayImage;
@end

MapOverlayRenderer.m

#import "MapOverlayRenderer.h"

@interface MapOverlayRenderer ()
@property (strong,nonatomic) UIImage *image;
@end

@implementation MapOverlayRenderer

- (instancetype)initWithOverlay:(id<MKOverlay>)overlay overlayImage:(UIImage *)overlayImage {

    self = [super initWithOverlay:overlay];

    if (self) {
        _image = overlayImage;
    }

    return self;
}

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {

    CGImageRef imageReference = self.image.CGImage;

    MKMapRect theMapRect = [self.overlay boundingMapRect];
    CGRect theRect = [self rectForMapRect:theMapRect];

    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextTranslateCTM(context, 0.0, -theRect.size.height);

    CGContextDrawImage(context, theRect, imageReference);    
}

@end

In my UIViewController, I am fetching the animated gif and adding the overlay by calling a method which contains the following code:

NSURLSession *session = [NSURLSession sharedSession];

    [[session dataTaskWithURL:[NSURL URLWithString:radarUrl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        self.radarImage = [UIImage animatedImageWithAnimatedGIFData:data];  //for animated radar image

        dispatch_async(dispatch_get_main_queue(), ^{

            [self.mapView addOverlay:self.polygon];

        });

    }] resume];

Any suggestions on how to animate a gif in an iOS 7 map view overlay would be greatly appreciated.

Verada answered 13/12, 2013 at 3:29 Comment(2)
I have done something like that for rendering weather information on MapView Do you want like that only?If yes then let me know i will explain you in detail.Cinelli
@iosRider Yes, please explain in more detail or submit as an answer.Verada
A
3

https://github.com/jhurray/iOS7AnimatedMapOverlay

this is the best way to animate overlays in iOS7

Afghanistan answered 22/1, 2014 at 19:20 Comment(3)
Link only answers are discouraged, can you summerize?Aldaaldan
Does this allow animated gifs to be displayed and animated in the overlay?Verada
Sorry about that. What you have to do to properly animate over a map in iOS7 is add an animating view to your MKMapView. You can no longer add subviews to overlays. That also means that every time the mapViewRegionWill/DidChange you have to remove and add it to the appropriate spot. The appropriate calculations are in the linked github project above.Afghanistan
D
1

Because a map view overlay is having your draw in a CGContext, it won't animate -- that is a buffer which is drawn to and translated to view contents, as opposed to being a normal part of the view hierarchy. Unfortunately you will need to make use of -setNeedsDisplayInMapRect:zoomScale: repeatedly to request animations. This system is a bit less flexible than iOS 6 and before, which added normal views atop the map.

Dint answered 13/12, 2013 at 23:30 Comment(7)
So how do I use setNeedsDisplayInMapRect for the animated gif?Verada
If if this way...I think you should probably setup a timer and call that 'setNeedsDisplayInMapRect' every interval? and ensure a new picture has been drawn in your 'drawMapRect' every time.Soler
@Soler So are you saying to use the timer to display each frame of the gif? Could you submit an answer explaining this in more detail?Verada
Yeah, this could get nasty, since you will need to calculate the current MKMapRect to cover the visible part of your image, but when you ask for the refresh with setNeedsDisplayInMapRect:, parts of it may load at different times. Depends on how fast your render routine is.Dint
@Dint I'm thinking it may be better to place a UIImageView into the overlay (if that's possible). That way I know the UIImage+animatedGIF category should work since it's made for UIImageView. However, I have no idea at the moment how to programmatically place a UIImageView into the overlay renderer. Suggestions?Verada
I don't think you're going to be able to do that with the new iOS 7 APIs. They are geared towards drawing static contents into a context as opposed to using a view hierarchy.Dint
@Dint Well there is a bounty posted for this question. So if you can figure it out, then you'll get some extra points!Verada

© 2022 - 2024 — McMap. All rights reserved.