0

I know this is pretty common, but I just wanted to know why this very simple code doesn't work.

I have a breakpoint in the NSLog line inside the webViewDidFinishLoad method and I'm inspecting the resulting UIImage (using quick look). The result is a blank image where the UIWebView should be (and the black background I placed there for debugging purposes).

#import "KIViewController.h"

@interface KIViewController ()

@end

@implementation KIViewController

-(void)webViewDidStartLoad:(UIWebView *)webView {
    NSLog(@"start");
}

-(void)webViewDidFinishLoad:(UIWebView *)webView {

    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    NSLog(@"webview did finish load");

}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIWebView *wv = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,640,200)];
    wv.delegate = self;

    NSString *url=@"http://www.google.com";
    NSURL *nsurl=[NSURL URLWithString:url];
    NSURLRequest *nsrequest=[NSURLRequest requestWithURL:nsurl];
    [wv loadRequest:nsrequest];
    self.view.backgroundColor = [UIColor blackColor];
    [self.view addSubview:wv];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Why is this happening and how can I prevent it?

João Pereira
  • 3,545
  • 7
  • 44
  • 53
  • Try adding the web view to `self.view` before loading the request in the web view. – rmaddy Sep 04 '14 at 23:28
  • It didn't work @rmaddy. – João Pereira Sep 04 '14 at 23:43
  • What exactly are you trying to do with the webview/image? – Mike Sep 05 '14 at 01:08
  • I'm using the exact same code and its working fine on my end.. – Mike Sep 05 '14 at 01:09
  • @Mike I'm just trying to see if that UIImage has the WebView's content. Here's what I'm getting with the code I posted: https://www.dropbox.com/s/r7ror8yjg843ufa/Screenshot%202014-09-05%2007.37.28.png?dl=0 – João Pereira Sep 05 '14 at 06:38
  • The first issue I noticed was that your frame is wrong, you're making it 640 wide and 200 tall, that's probably one reason it looks weird. – Mike Sep 05 '14 at 13:01
  • Actually I did that on purpose. I wanted to display the picture below the actual UIWebView but I ended up using the debugger instead since I just wanted to see if I could actually see the picture. – João Pereira Sep 05 '14 at 13:41

1 Answers1

1

I've had this problem too once. There is a slight delay between when the delegate function, webViewDidFinishLoad: is called, and when the webView content is drawn to the screen. The content exists and is stored in the webView. Just that it's not rendered on-screen. I don't know why this occurs, but I guess it is because the rendering process of a webView takes longer than the average UIKit object (owing to vector graphics).

In my case, I needed to adjust the size of the frame of the webView based on the loaded content. And so, I did all my frame adjustments on the main thread and called the screenshot function from a background thread. Something like:

dispatch_async(dispatch_get_main_queue(), ^{
    /*
     do some adjustments here
    */

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    });
});

As far as thread safety is concerned, I found this in another answer:

Core Graphics and Core Animation being low-level APIs, are generally thread safe. However, the same rules about access still apply: Any work must not be accessed by more than one thread at the same time, else drawing will fail and your app will crash. I would be wary (but not afraid) of UIImage, as UIKit objects aren't just not thread safe, they're basically ticking time bombs in background threads, and will happily dive straight off a cliff into Exception Land for no good reason. However, because UIImage is just a CGImage wrapper, again ,most drawing is thread safe.

Hope this helps.

Community
  • 1
  • 1
Tcharni
  • 644
  • 1
  • 6
  • 17