This seems like a common problem, but I'm unable find an adequate solution. I'm trying to re-size a bunch of UIWebViews to fit their content, but it doesn't seem to work properly. The best solution I've found so far is this answer, but it only appears to work occasionally in my solution. The idea is to re-size the UIWebView in the webViewDidFinishLoad:
delegate method. However, this still doesn't get the right size. If I trigger the update at some undefined time after webViewDidFinishLoad:
, the content does get sized correctly.
I will describe my situation below, and I'll paste relevant source on Gist.
Problem Description
I have a situation where I'm getting data from a JSON API and displaying the data in webviews. The API returns an array of objects, and each object has a "content" field with HTML-formatted text. The designers have given a structure which involved a (mostly) hidden view that you swipe up to reveal, which contains a scroll view of all the content, formatted in a very particular way.
To implement this, I have three view controllers: The main view controller, the secondary view controller which you swipe up on the main view controller to reveal, and a tertiary view controller that displays one item of html-formatted content from the JSON API results.
The secondary view controller contains a UIScrollView and an array of tertiary view controllers. Each tertiary view controller contains a UIWebView to display the HTML-formatted content, and labels for displaying other attributes of the JSON object. Because the tertiary views will be displayed inside a UIScrollView in the secondary view, the tertiary views' UIWebView needs to be re-sized to fit its content and have user interaction disabled in order to prevent a confusing scroll-view-in-scroll-view scenario.
The process to get all this to work is as follows:
- First, on the Primary controllers ViewDidLoad, load up and display the secondary view and an activity indicator so the UI does not appear to freeze
- Next, load the data from the JSON API
- When the data from the API has loaded (notified via a delegate), construct tertiary view controllers, set their attributes from the loaded data and add them to the secondary controller's list.
- Once that is finished, call the Secondary controller's setup method. This method loops through the list of tertiary controllers and calls their setup methods in turn
- Each tertiary controller's setup method sets the text for the labels and sets the
content for the UIWebView using
loadHTMLString:
with a pre-defined html file's content, with the content of the JSON object substituted in. - On the tertiary controller's
webViewDidFinishLoad:
delegate method, using the method at this answer, re-size the web view based on the content size. - Re-size the tertiary controller's view to fit the web view and position any labels that go underneath the web view
- The tertiary controller then calls a delegate method to notify the secondary controller that it has finished loading. The secondary controller keeps tabs on which of its tertiary controllers have finished loading.
- When all tertiary controllers are finished loading, the secondary controller loops through its list and adds the tertiary views to it's UIScrollView's content, adjusting frames and the content height as it goes.