Is it a good idea to add uiwebviews in table cells? - iphone

I have several local html files and I want to show them in a table with static(for now) cells.
Each UIWebView would have a different height (I dont want to have any scrolls in the UIWebView) so obviously each cell has a different height. Most of the comments i read discourage the usage of UIWebView in table cells. What do you think : is this applicable ? will it be slow and need time to load?

UIWebview in tableview cells will affect the performance for sure. To display Html content in tableview cells you can use NSAttributedString.

I used a UIWebView in an app to display content coming from the web as rows in a table view.
I know that doing that is discouraged, due to the high memory use of UIWebView, but in my case it was not only a matter of displaying rich text: I had to display HTML loaded from the web, so I give that option a try. In short, I tried it and it worked fine.
The app got memory warnings from time to time, but it was also able to recover memory effectively and run unaffected even on an ipod touch (just 256MB of memory). Performance was possibly affected, but due to the fact that the app was doing just that (loading text from the web and displaying it in the table), the app was perfectly responsive.
One important notice: pages were pretty simple, just text, and each table did not contain more than 15 elements. Furthermore, one thing you have to consider is that the UIWebView introduces a small delay in the rendering, so you will have to deal with it and accept it in your app (there is no way to get rid of it that I know of).
In a later project, I used a different approach: using just one UIWebView and creating the table using HTML/js inside of it. Well, it also worked, but I could not see any big improvement as to peak memory usage nor performance (I checked with instruments).
This is just my experience, I am not trying to say that this will work or that is good practice to do. In any case, I hope it helps.

Related

Displaying Lots Of RichText : Choosing the best option

What is the best way to display lots of RichText (HTML formatted)
At the moment I'm working on an app for a forum. As you'd expect the posts on the site have lots of HTML formatting, lists, images bold text, colored text, etc...
Now there are several options I can think of (non of them ideal, please if you think of any other options post them in the comments):
Custom Cells using NSAttributedString+HTML + DTAttributedTextView for each post?
Problems: I used the NSAttributedString+HTML categories in the app elsewhere and it was less then ideal, creating an NSAttributedString seems to be quite expensive (slow) even in small amounts.
For 10+ posts each of which may be the length of an entire article would be awful + although DTAttributedTextView supports the IMG html tag (an most tags) it doesn't support remote loading of images unless you specify their width and height in the img tag. And for a forum where an IMG tag could be a smiley (10*10) or a screenshot (640*960) there's no way to predict that.
(Since writing this NSAttributedString+HTML, which is now renamed DTCoreText, has added full support for <img> tags and improved greatly!)
Custom Cells with a UIWebView in them for each post?
This one I considered for quite a while, however when reading this blog post I realised a problem that would cause, Smooth scrolling. The idea of having a native application for a site is that it is better then using a simple UIWebView to view the sites mobile theme. If the app lags and is jerky while scrolling that is worse not better (also as I need to display images hiding the webview's like he suggests wouldn't work). Also UIWebView's need to be created on the main thread or they break.
Back to the UIWebView?
Annoyingly besides doing a pathetic cheat, (like in the iFans app) where you only display text and then if they click it a UIWebView loads with all the nice images etc..., the only option left seems to be to do what I think the TapaTalk app does and have the entire thread view as a UIWebView. This isn't too bad as it will probably have quite good performance and will allow me to possibly add user controlled themes etc.. but I find the idea of using a UIWebView in a websites native app repulsive.
Does anyone have any experience creating web powered app, like maybe a facebook client, forum app, or new site app which had to display content from the site (I don't really count a twitter client as it only has to deal with text & links in small amounts per post). Or any ideas on the best way to display RichText content in an iOS app?
Any idea's would have to deal with the lot:
Multi Coloured Text.
Right, Left & Center aligned text.
Images (of variable size).
Bold text.
Text of different sizes & fonts.
Underlines text.
YouTube Videos.
HTML tables.
Just in case the actual question wasn't very clear in all of that I'll sum it up:
"What is the best way to display lots of RichText (HTML formatted) content for a forum client app"
So if I am reading this right, you want the forum posts of a given topic to be cells of a UITableView and the cells need rich formatting?
Assuming this is correct, I imagine each post will take up a lot of the screen (large cell height). In this case, having a UIWebView as a subview might not be as bad performance-wise as you might think. UITableView reuses cells so really only the visible cells need be loaded into memory.
I'm also assuming you are able to access the forum via an API, right? In which case, you should be able to pre-load data immediately prior to loading the view and the UIWebViews will only be used for formatting. You can even load a CSS file from your app bundle when you loadHTMLString into your UIWebView so you're not loading that from a server every time.
All that being said, if you did have a lot of concurrently visible cells it might be a different story and I'd maybe consider only showing plain text in the UITableView index and displaying the rich formatting only when the user taps the cell to view the single post. This might also be better from a design standpoint as having a ton of differently formatted cells on screen could potentially end up looking a bit sloppy.
Also, this may be obvious (especially since you seem to be both performance and design conscious) but please don't use UIWebView for UI controls. Any time I see a UIWebView tab bar or fake navigation bar I cringe (ack, Netflix). For formatting though, a lot times it's the only way to fly if you're loading a lot of dynamic content from a server.
NSAttributedString+HTML already supports lazy loading of images. See the Demo that shows how to do that. It's reasonably fast but you want to hold of parsing the HTML for content that is not on screen.
It mostly depends on what UI you want to achieve. NSAS+HTML is meant for situations where you control the quality of the HTML (i.e. because you generate it yourself). There it affords you with an unprecedented level of control over the view hierarchy because you can embed your own custom views to show images.
In other cases where you cannot be sure about the quality of the HTML you have to use UIWebView and work around all of it's limitations, one being that it takes enormous amounts of RAM and it slow to show the contents. Also UIWebView is not thread-safe (because WebKit is not).

What's a good general approach for apps like pulse, youtube, NYTimes, etc? Use UIWebView or something else?

That may seem like a broad question, but I'm talking specifically here about apps that display a lot of content (image plus some text) pulled from the net in separate cells, rows, etc. And where each of those cells can get loaded asynchronously (independently from all the others).
So for example, for iOS, is it too inefficient to use uiwebview for each of these cells? It seems like this would be a simple approach, but I'm not sure about the performance. "Pulse" has a bunch of cells on the page at one time, and on iPad this could really get to a large number. Is it better to do this using lower level techniques, or is using UIWebView a decent choice?
Update:Clarification-->
Just to clarify, I understand that the typical approach is to use UITableView and then create table cells to hold and show the data (although the "Pulse" UI may be more involved). What I'm getting at here is if those UITableViewCells could hold UIWebViews? So instead of putting a UIImageView and a UITextView in each cell and so forth, if it makes sense to just put UIWebViews there instead, and give them URLs (could pass a param to indicated the row) to load as cellForRowAtIndexPath is called or something.
Well, if you talk about the YouTube app, its not UIWebview. The common and better approach is to use UITableViews along with the custom UITableCells. As far as asynchronous loading of images is the concern, we implement "Lazy Loading" mechanism. And in this way, we are able to keep the performance benefit of native UIView intact. Whereas, in UIWebView, you would need to design the iphone based webpages which will cost you learn about Dashcode tool, or may be someother opensource css library, etc.
In short, UITableView, with Custom UITableCells, along with Lazy Loading Mechanism (achieved by some Threading Techniques) will do all the Magic for you.
Hope this answer will give you some better idea....
Do not use UIWebViews with UITableViews like that. There are far too many moving parts for a UITableView!
I wrote the NYTimes iPhone app while I worked there. I only ever used a UIwebView to display article content. This is because NYT articles and log post layout is extremely complicated and impracticle to replicate programmatically. (I did override some of the CSS in app)
The UITableView is a super high performance implementation for butter smooth high speed scrolling. UIWebViews are the opposite of that: heavy, slow and memory intensive. In fact web views actually run internal virtual machines and threads (for JavaScript, rendering, etc).
Keep in mind that table view cells are recycled very aggressively. The instant a cell scrolls off screen bottom it will, in gneral, be immediately reconfigured for use as the new cell that scrolls in from the top.
With a UITableView, you need to create VERY highly optimized custom UITableViewCells. The data displayed in the cells should be cached aggressively by you so that you don't need to recompute it or perform intensive layout calculations. Uncacheable information such as remote images should be loaded asynchronously (which might mean they show up much later).
On caching:
The NYT apps have a high performance caching system for images. The trick is to request the imge data as soon as its "needed", but to also preempt downloading images which were needed a second ago, but no longer. You also don't want to cancel partially downloaded images because that wastes the already consumed bandwidth. Check out NSOperationQueue. It has most of the levers needed to build such a system.
Another note: consider building a web app if your project may also be accessed via web or an android app.

Improve UITableView scrolling performance while loading images

I have a scrolling grid of photos that looks and functions pretty much exactly like the photo picker on the iPhone. It is constructed from a UITableView that uses a custom UITableViewCell which displays a row of photos (very similar to how Three20 implements it).
It works great except that scrolling performance is poor. I'm already following most of the best practices for fast UITableView scrolling (à la Tweetie).
The images are all bundled with the app. I load them on the UI thread, on demand. I use UIImage's imageNamed: so that the images will be cached after they're first loaded. Once I've scrolled through the table view once, it scrolls very smoothly.
The problem is, the first time scrolling through the table view, scrolling is jittery. I've profiled the app and found that the majority of the time is spent loading the images from the file system. They are JPEG images, already sized correctly (small). I tried using PNG images instead, but performance doesn't improve very much.
The iPhone photo picker exhibits much better loading performance. I'm wondering if combining all the photos into a single image, which I load once and then split into smaller images would be faster. It certainly works in games, but I know that's really a totally different story. Has anyone had experience doing that?
Any other ideas for how I can improve performance?
Incidentally, I'm having a similar, albeit less, performance problem for another UITableView that just uses standard UITableViewCells with one image assigned to the imageView per row.
One thing to try could be pre-caching all the images when the view loads. Beyond that, perhaps loading the images in the background (even though it's loading from the filesystem and not the web). I haven't tried this myself, but perhaps you could use something like https://github.com/rs/SDWebImage and have the URLs point to the filesystem. Users might see some placeholder images at first, but then the UI wouldn't stutter while images are loading.
Setting the PagingEnabled property to off improves the scrolling performance.
I had a similar issue using a UITableView to display information parsed from an RSS Feed. I ran into scrolling performance issues when there was a significant amount of data. Though I'm still working on it I suspend the parsing when the table is being scrolled. It resumes when scrolling stops. I am not at my computer, but I believe I used tableViewDidScroll and tableViewDidEndDecelerating. You can check these tableview delegates. In any case it works very well, I just need a more elegant way to pause my parsing.
Fantastic. That does work like a charm! So efficiently I ended up using insertRowAtIndexPath rather that reloading the table. Now it behaves the way it
Thanks so much!
Joe

Bubble Chat + Emoticon + UITableViewCell

This is a question for iPhone development and I'm hopin someone can point me to the right direction on how i should go about implementing this.
I am trying to write a chat application that supports emoticons/smileys. Where the smiley/emoticon images are stored can be figured out later. I think few iphone applications out there are already doing this (i.e. skype + ebuddy(?)) but not sure what method they went for.
After searching around, there seems to be a few ways of doing this (i think):
bubble chat style which has been discussed before. UITableViewController with custom UITableViewCell. For emoticons, might have to do a whole bunch of calculations to determine where to stick a UIImageView for each emoticon.
Use UIWebView as the whole "window". Style it to look like bubble chat. Takes away any manual calculations on image smiley placements.
I have no idea what the performance is like for each of these two methods, how complex it can get etc, so any comments and guidance will help for sure. Cheers
If you use custom UITableViewCell, then I'd probably implement drawRect: instead of adding labels and images. One will probably take as long to implement as the other, but it will perform much better.
The UIWebView might be worth a short, although you will have to make sure that everything looks right there, too. Instead of using one big web page, I suggest simply throwing in a web view into each table view cell.
Personally I prefer the first approach, measuring and layout of text is not too complicated, but then I've never been the ultimate HTML guru.
I agree with #Eiko on making custom UITableViewCells, especially using drawRect instead of adding labels, images, etc.
If you used a UIWebView how would you handle updating it? A complete reload each time new text is sent? That seems like it will be a cause of issues. Once you get a long conversation reloading the entire UIWebView's contents will cause some flickering which isn't acceptable in my opinion. Also using a UIWebView would require you to have 2 complete copies of each conversation in memory. 1 as your backend data and 1 as the HTML. Where using a UITableView you have your backend data, and only enough of that will be duplicated that can fill 1 screen at a time.

Better way to have a photo slider/thumbnails on iPhone?

I have a probaly large list of images and want something like the photo app but with custom toolbar.
I wonder how do this. I see the sample of Apple http://developer.apple.com/iphone/library/samplecode/Scrolling/index.html but that not will work for a large set of images.
I have a product list and some of my customer need download as much as 12,000 products in the device (I have a solution for the PocketPC I'm porting to iPhone).
In this thread How make a view of thumbnails in landscape mode? somebody suggest is possible use a TableView, but then I'm not sure... mainly how hide the section caption then could be...
UPDATED correct the link
The "Scrolling" demo won't work as-is for a large image set, but some minor adjustments can easily fix that. The trick is to use UIScrollView delegate methods to load images on demand and then unload them after they disappear. For decent performance you'd want the central image and one or two on either side to be loaded-- meaning that you can extend that design to support as many images as you like but still never have more than 3-5 in memory at a time.
The Stackoverflow link you post doesn't actually mention table views, so I'm not sure what approach you have in mind there. If by "section caption" you're referring to section header and/or footer text, then just don't provide any. Table views don't have a default for this, so if you don't give one to a table view then it won't show one.