问题
I'm using a UIWebView. I call a web service to get the content for that. In web service response I get HTML string as below:
<div style='text-align: center;'> <div style=' display: inline-block; width: 120px;height: 120px; text-align:center; '; ><img src='http://assetdetailsdemo.azurewebsites.net/QRUpload/4774.jpg' style='height:100px; width:100px' /><br /><div>4774</div></div> <br /><br /></div>
This is just an example. I may get 'n' number of above kind of 'div' tags which may have images 1 in each. I have load this in UIWebView using:
[_webView loadHTMLString:_HTMLStr baseURL:[[NSBundle mainBundle] bundleURL]];
where _HTMLStr contains above HTML string.
My main issue is I have a requirement to get hole content of UIWebView and need to generate an image. I have already tried below code to get the image:
UIGraphicsBeginImageContext(_webView.bounds.size);
[_webView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
This method avail me to convert the content of UIWebView to UIImage. But, I want a pice of code which allow me to generate image only from the content of webview. Or we can say that I'm finding another method to get the image.
回答1:
So I've experienced the same issue here. After a while struggling with it, I found out that:
loadHTMLString:baseURL:Doesn't actually load the string. It'll perform lots of stuff then callback in the delegatewebViewDidFinishLoad:(UIWebView *)webViewYou'll have to keep the VC until it rendered the HTML. Otherwise, the VC will be disposed before the calling back delegate
webViewDidFinishLoad:. In my case, I use singleton object to retain it.
Solution:
- Create singleton object of the VC.
- Set webView.delegate = VC
- Implement the image rendering in
webViewDidFinishLoad:(UIWebView *)webView - You can store a callback or a delegate or something to notify back that the webView has completely rendered.
EDIT:
Because loadHTML doesn't actually load right away, but perform something (not sure what it does tho...) then callback when complete in webViewDidFinishLoad:(UIWebView *)webView, therefore you'll need to wait until that method got called.
So, you declare webView and callbackBlock in your VC (or any object, depend on you):
@interface MyObject () <UIWebViewDelegate>
@property (strong, nonatomic) UIWebView *webView;
@property (strong, nonatomic) void(^callbackBlock)(UIImage *generatedImage);
@end
So when you call generateImageFromHTML:(NSString *)html callback:(callbackBlock)callback, it'll wait until the image completely generated then callback.
You'll need something to retain the webView and callbackBlock. In my case, I just use singleton to keep it.
+ (instanceType)loadHTML:(NSSTring *)html callBack:(callbackBlock)callback {
static dispatch_once_t onceToken;
static MyObject *instance;
// Keep reference
dispatch_once(&onceToken, ^{
instance = [MyObject new];
instance.webView = [UIWebView new];
instance.webView.delegate = instance;
instance.webView.scalesPageToFit = YES;
});
// Perform load here
[instance.webView loadHTMLString:html baseURL: [[NSBundle mainBundle] bundleURL]];
// Wait until done
instance.callbackBlock = callback;
return instance;
}
Next is actual create the image from htmlContent image and return it:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if (self.callbackBlock) {
self.callbackBlock([self imageFromWebView:webView]);
}
}
- (UIImage *)imageFromWebView:(UIWebView *)view
{
// Adjust the image size to fit webContent
// get the width and height of webpage using js (you might need to use another call, this doesn't work always)
// CGFloat contentWidth = [view stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName(\"content\")[0].offsetWidth"].floatValue;
// CGFloat contentHeight = [view stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName(\"content\")[0].offsetHeight"].floatValue;
CGSize documentSize = CGSizeMake(contentWidth, contentHeight);
view.frame = CGRectMake(0, 0, contentWidth, contentHeight);
//make the snapshot
UIGraphicsBeginImageContext(documentSize);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
来源:https://stackoverflow.com/questions/42644944/get-uiwebview-content-and-convert-it-to-image