Doug Smith
Doug Smith

Reputation: 29326

How to show a GIF on iOS in a certain frame, not show it until fully loaded, and allow zoom?

When a user selects a GIF, I want to present an overlay on top of everything showing the GIF.

I know there's a few ways on iOS to do this. There's the great UIImage+animatedGIF which works decently well, but for longer GIFs they're very slow and don't play back at the same speed as a UIWebView would (which plays at the accurate playback speed).

It sucks, because if that category didn't play them back slowly it would do everything I need.

But it doesn't, so I tried with UIWebView, however I'm confused about three things:

  1. How do I get size that the UIWebView should be when presented (its frame)? Would I have to download the GIF first as a UIImage then check its size property? Is there a better way (might take awhile)?

  2. How do I stop it from playing until it's fully loaded?

  3. With the above category, as it's just a UIImage, when I embed it as a UIImageView in a scrollview it's very easy to zoom in and out of. Is this possible with a UIWebview?

Upvotes: 5

Views: 3141

Answers (5)

Tomskiis
Tomskiis

Reputation: 134

you can get the Size of a UIWebView by checking it's UIScrollView

webview.scrollView.frame

Kind of hacky but this usually works for me in getting the size of the content inside the webView.

Then check it's has loaded by using the delegate as Sha suggested

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
... Show Web View
}

Upvotes: 1

Bishal Ghimire
Bishal Ghimire

Reputation: 2610

You can use SDWebImage it has Animated GIF support

https://github.com/rs/SDWebImage/blob/master/SDWebImage/UIImage%2BGIF.m

        _block BOOL flag = NO;
        NSURL *imageURL = [NSURL URLWithString:@"ImageUrl" relativeToURL:@"mainURL"] ;
        SDWebImageManager *manager = [SDWebImageManager sharedManager];
        [manager downloadWithURL:imageURL
                         options:0
                        progress:^(NSUInteger receivedSize, long long expectedSize)
         {
         }
                       completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished)
         {
             if (image){
                 flag = YES;
                 downloadProgress++;
             }
         }];

Upvotes: 2

Jay Zhao
Jay Zhao

Reputation: 956

I would suggest using OLImageView. It has accurate playback.

It also supports incremental loading so you will know the frame as fast as you can.

+ (instancetype)imageWithIncrementalData:(NSData *)data;

Also you can pause the animation just by calling stopAnimating .

For the overlay, you can create a MyGifContainerView that contains both OLImageView and MyOverlayView, should be easy to do.

Upvotes: 1

Pochi
Pochi

Reputation: 13459

If the overlay you are trying to show is something like a dimmed background in where the image is set on the middle and judging by the type of loading you are trying to get. I would use an UIView with an image view, a web view and an activity indicator or something to show the loading.

User presses the gif, you show the UIView with the UIImage view with a background color of black (for example) and with a certain alpha (0.7) which will be the dimmed background, you should also show the activity indicator running, and be sure that the web view is hidden.

Once the web view has finished loading and using the "webViewDidFinishLoad:" delegate method, you can get its size and adjust it accordingly inside the view, then set the webview hidden property to NO (and dont forget to hide the activity indicator too).

The "@property(nonatomic) BOOL scalesPageToFit" from the UIWebView controls the user being able to zoom:

If YES, the webpage is scaled to fit and the user can zoom in and zoom out. If NO, user zooming is disabled. The default value is NO.

Additionally, you might want to show a second UIImage view with the preview of the gif (the one you are using to show the user to select the gif will work) Then just hide the image view and show the webview when the gif is ready to be displayed.

Upvotes: 1

Segev
Segev

Reputation: 19303

1.

The first solution that comes to mind is to set the background of the webview to clear color and place it in the right location after it finishes loaded. Usually I use

[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"]

but that won't work if you are directing your webview to a gif url.

2.

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    webView.alpha = 1;
}

That way the UIWebView will be shown to the user only after the gif is full loaded.

3.

[webView setScalesPageToFit:YES];

Upvotes: 2

Related Questions