Reputation: 3565
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?
Upvotes: 0
Views: 986
Reputation: 644
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.
Upvotes: 1