ios - Resize UIWebView on webViewDidFinishDownload dilemma -
suppose have uiwebview that's stacked against uiimageview (or other view):
i want resize uiwebview know put uiimageview. way wait uiwebview finish loading:
webviewcalculating = yes; while (webviewcalculating == yes) { [[nsrunloop currentrunloop] runmode:nsdefaultrunloopmode beforedate:[nsdate distantfuture]]; }
then resize when uiwebview has finished loading, according this suggestion:
-(void)webviewdidfinishload:(uiwebview *)webview { cgrect frame = webview.frame; frame.size.height = 1; webview.frame = frame; cgsize fittingsize = [webview sizethatfits:cgsizezero]; frame.size = fittingsize; webview.frame = frame; heightsofar += webview.frame.size.height; webviewcalculating = no; }
after point, i'd know how tall uiwebview is, , can place uiimageview accordingly. when push view controller , came this, hacky [[nsrunloop currentrunloop] runmode:nsdefaultrunloopmode
doesn't seem wait until webview finished calculating height first. there better way me know size of uiwebview without waiting load? maybe similar sizewithfont
method of nsstring?
you should not doing while loop pumping run-loop. bad idea. should have scroll view container respond , relayout subviews when webview finishes loading. start "reasonably sized webview area". maybe show spinner in pace while web content loading.
a technique i've used follows:
firstly add category methods uiwebview follows:
@interface uiwebview (contentsize) - (cgfloat)documentoffsetheight; @end @implementation uiwebview (contentsize) - (cgfloat)documentoffsetheight { return [[self stringbyevaluatingjavascriptfromstring:@"document.documentelement.offsetheight"] floatvalue]; } @end
then i've written uiview subclass contains uiwebview. eg:
@interface mywebview : uiview <uiwebviewdelegate> @end @implementation mywebview { bool _loaded; uyiwebview *_webview; } - (id)initwithframe:(cgrect)frame { self = [super initwithframe:frame]; if (self) { _webview = [[uiwebview alloc] initwithframe:cgrectmake(0, 0, frame.size.width, 1)]; _webview.delegate = self; _webview.alpha = 0.0f; [self addsubview:_webview] } } - (cgsize)sizethatfits:(__unused cgsize)size { if (_loaded) { cgfloat height = [webview_ documentoffsetheight]; cgfloat width = self.frame.size.width; return cgsizemake(width, height); } return self.frame.size; } - (void)sizetofit { cgsize fittingsize = [self sizethatfits:cgsizezero]; self.bounds = cgrectmake(0, 0, fittingsize.width, fittingsize.height); } - (void)layoutsubviews { [super layoutsubviews]; _webview.frame = cgrectmake(0, 0, self.bounds.size.width, self.bounds.size.height); } - (void)loadhtmlstring:(nsstring *)htmlstring baseurl:(nsurl *)baseurl { // code assumes jquery used in html content. if not, added script resource here too. nsstring *scripttag = @"<script type=\"text/javascript\" >jquery(document).ready(function() { window.location = 'x-webview://ready'; });</script>\n"; nsstring *const headopeningtag = @"<head>"; if ([htmlstring rangeofstring:headopeningtag].location != nsnotfound ) { htmlstring = [htmlstring stringbyreplacingoccurrencesofstring:headopeningtag withstring:[headopeningtag stringbyappendingstring:headcontent] options:nscaseinsensitivesearch range:nsmakerange(0, [htmlstring length])]; } else { htmlstring = [headcontent stringbyappendingstring:htmlstring]; } [_webview loadhtmlstring:htmlstring baseurl:baseurl]; } - (bool)webview:(uiwebview *)webview shouldstartloadwithrequest:(nsurlrequest *)request navigationtype:(uiwebviewnavigationtype)navigationtype { if ([request.url.scheme isequaltostring:@"x-webview"] && [request.url.host isequaltostring:@"ready"]) { _loaded = yes; [uiview animatewithduration:0.1 delay:0 options:uiviewanimationoptionallowuserinteraction animations:^{ webview.alpha = 1.0f; } completion:nil]; [self sizetofit]; return no; } return yes; } @end
so uiview subclass embed invisible _webview. when document has loaded , rendered jquery based javascript tries navigate away current page using custom url scheme. navigation trapped denied. in response view sizes fit , gets proper size html document.
note don't have use jquery. can add dom javascript event. i'm more familiar how jquery things raw dom events.
in case have communicate scrollview content has finished loading , scroll view views should re-layout. can delegate protocol or similar. or maybe scrollview "mywebview" container uiview subclass. adapt needed.
Comments
Post a Comment