Deferring viewWillAppear until webViewDidFinishLoad
I have an application that uses
UIWebViews in several view controllers. The
UIWebViews are used to render locally generated html, no slow network access required.
To save memory I only load these on demand as prompted by the viewcontroller
viewWillAppear callback. (And unload offscreen instances in response to
The problem is that the user gets to see the html being rendered, sometimes accompanied by flashes of styling and other assorted unpleasant artifacts. I would much rather the rendering be done offscreen, and reveal the fully rendered view when its ready.
It would be very tidy to be able to have the
viewWillAppear not return until the UIWebView is fully rendered. But how?
I tell the
UIWebView what to render by sending it a
loadHTMLString:baseURL: message. This is asynchronous, and some time (soon) later the webview's delegate gets called back
I experimented with running a runloop inside
viewWillAppear, running either the
UITrackingRunLoopMode. This works in the simulator (it complains to the log
[CATransaction synchronize] called within transaction
but does work) but on a device it deadlocks, with
webViewDidFinishLoad never being called.
(Also, it seems like the
UIWebView loading property doesn't work. At least, after I call
loadHTMLString:baseURL: and before getting the callback it's not true.)
No correct solution
Lots of solutions here I think. A quick one is to load your UIWebView with it's hidden property set to YES. Then set your UIViewController as the UIWebViews delegate and implement:
- (void)webViewDidFinishLoad:(UIWebView *)webView
where you set the property back to NO.
A thing to note is that webViewDidFinishLoad will fire more than once if you have framed/embedded content. So you have to keep track of this. Shouldn't really be a problem if you are loading local content.
I like monowerker's solution best, but another solution would be to hold onto the already-rendered UIWebView all the time (in some more permanent object than the view controller). I'd only do that if the look of monowerker's solution is too disruptive.