3

I'm building an RSS Reader for iPhone where I get articles and their HTML from the server and I want to display this list of articles for the user in a UITableView.

I've explored options like DTCoreText to be able to use HTML with a UILabel or UITextView, but it unfortunately just doesn't offer rich enough support of all the HTML I could be dealing with. So UIWebView or WKWebView seem like my only options for accurately representing the content.

The problem lies with how content having varying height. Detecting the content's height isn't too bad, but when you use it with a UITableView, the table view asks for the heights of all the rows first, and with web views you have to load the content first, and then in the callback for having finished loaded, only then can you find out the height. Which is annoying, because in my case the HTML is simple enough that it takes very little time for the web view to render it.

So you have this issue where the table view asks for the height of a row, and you basically say "Just a second, take this random value for now and I'll tell you in a second when I find out." This works terribly, because when you're scrolling through the table it takes the intermediate value, then loads content after and updates, causing a jump, which is especially bad if you're scrolling up as you're being bounced around as the heights for the rows above you are being calculated. Caching the height the first time you see it doesn't seem to work either, because the user can rotate the device and have that cached value be invalid.

So I'm wondering, is there any way to be able to use web views in a table view?

Community
  • 1
  • 1
Doug Smith
  • 29,668
  • 57
  • 204
  • 388

1 Answers1

1

You can if you've preloaded the web content. Simply modify your approach and don't tell the table view the rows exist until you have the web content for that row. Then once the content is loaded you can get its height and insert the row at the bottom of the table view. Continue this process until all the content is loaded.

InkGolem
  • 2,662
  • 1
  • 15
  • 22
  • Could you elaborate? How might I go about doing that? – Doug Smith Mar 02 '15 at 17:31
  • @DougSmith Start with an empty `NSMutableArray` that your `UITableViewController` uses to populate its `tableView`. Start your asynchronous requests load the content. As each one comes back, add the `UIWebView` to the end of the array. Then call reload on the `tableView`. In `heightForRowAtIndexPath` you ask the `webView` for that row what its content size is and return the height. In `cellForRowAtIndexPath` you put the `webView` in the cell. – InkGolem Mar 02 '15 at 20:26
  • Having potentially dozens of `UIWebView`s in an array seems like a memory nightmare. – Doug Smith Mar 03 '15 at 17:23
  • @DougSmith it does. That alternative would be to let the web views load the content, ask for the size, and just save off the size. Then reload the content when the cell with the web view comes on screen. – InkGolem Mar 03 '15 at 20:46
  • @DougSmith The crux of your problem is that you don't know how big it is until you load it, and you have to know how big it is before you load it. That means you either do what I described, or don't use a `UITableView` to solve your problem. – InkGolem Mar 03 '15 at 20:47
  • The issue these is that the number becomes useless when rotating to landscape. And yeah, I understand, I just wish there was a synchronous way to ask for the height without having to wait, it's near instantaneous in this case so having to defer it until later is really silly and complicates this so much. – Doug Smith Mar 03 '15 at 20:49
  • @DougSmith You're correct. That's why most RSS readers have a couple different styles of cell with fixed sizes and layouts that they populate with content. Then the user taps the cell to navigate to the full content. – InkGolem Mar 03 '15 at 20:51
  • @DougSmith I know that's not the answer you wanted to hear, but would you mind accepting the answer? :) – InkGolem Mar 03 '15 at 20:53
  • I'm going to wait a little while longer to see if anyone else chimes in, I don't want to close the books quite yet. – Doug Smith Mar 03 '15 at 20:56
  • @DougSmith I'm curious as to whether anything came of this. Did you find something more elegant? – davextreme Jun 03 '16 at 15:20
  • @davextreme I did not. :( – Doug Smith Jun 07 '16 at 15:55
  • I got same issue, I haven't tried yet but i will do this way - I am going to start wkwebview to load html. When it's all finish i will add WkWebView as an object in to an array. Which it's going to be a static object and I hope it' won't make any problem to me. Regards. – Onder OZCAN Oct 04 '16 at 07:01
  • @InkGolem why can't you add screenshots or video to get more up votes. Video or screenshots will be more helpful – Arshad Shaik Nov 24 '21 at 06:07