Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 05-19-2010, 08:01 PM   #1 (permalink)
Registered Member
 
Join Date: May 2010
Location: Montreal, QC
Posts: 9
Craftpaper is on a distinguished road
Send a message via Skype™ to Craftpaper
Arrow Pb : How to make a beautiful UITableView w/ Custom Cells without scrolling lag

Dear Everyone!

Here is the problem :
I (then helped w/ an other developer) tried to make a Custom UITableView for the app of a girl's blog.
First it was a success because the XML feed was fully usable, and I could add without so much problems a custom Cell with an Image for each :



The problem is that I have a big problem of memory, the scrolling is very awful.
Of course, I've googled it, and changed so many things (imageWithContentOfFile instead of imageNamed, a function for static cell height, used a static Cell Reuse, used an analyzer for potential leaks ...)

I need your help, guys! So if someone has a little time to see the code right there, and a little advice, it would be awesome!

Code:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *) indexPath
{
    return 80.0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	
	static NSString *MyIdentifier = @"MyIdentifier";

#if 0
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
#endif
	
	cell = (MainCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
	if (cell == nil) {
#if 0
        
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
       
#endif
        
        [[NSBundle mainBundle] loadNibNamed:@"MainCell" owner:self options:nil];
	}
	
	// Set up the cell
	int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
	[cell.topLabel setText:[[stories objectAtIndex: storyIndex] objectForKey: @"title"]];
	[cell.bottomLabel setText:[[stories objectAtIndex:storyIndex] objectForKey:@"summary"]];

	NSMutableString *imgstr = [[stories objectAtIndex:storyIndex] objectForKey:@"image"];
	// clean up the link 
	[imgstr replaceOccurrencesOfString:@" " withString:@"" options:0 range:NSMakeRange(0, [imgstr length])];
	[imgstr replaceOccurrencesOfString:@"\n" withString:@"" options:0 range:NSMakeRange(0, [imgstr length])];
	[imgstr replaceOccurrencesOfString:@"\t" withString:@"" options:0 range:NSMakeRange(0, [imgstr length])];
	
	NSURL *imgurl = [NSURL URLWithString:imgstr];
	NSError *err;
	NSData *imgdata = [NSData dataWithContentsOfURL:imgurl options:NSMappedRead error:&err];
	
	cell.logoImage.image = [UIImage imageWithData:imgdata];
	[cell.logoImage sizeThatFits:CGSizeMake(80,80)];
	
	cell.topLabel.font=[UIFont fontWithName:@"Georgia" size:14];	
	
	cell.logoImage.layer.masksToBounds = YES;
	cell.logoImage.layer.cornerRadius = 5;    //4.5
	
	[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
	
	return cell;
}
For the background :
Code:
- (void)viewDidLoad {
	
	newsTable.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"fondCell" ofType:@"png"]]];
	newsTable.separatorColor = [UIColor clearColor];

}
Thanks! If you need more informations, juste ask!

Séraphin

Last edited by Craftpaper; 05-19-2010 at 08:04 PM.
Craftpaper is offline   Reply With Quote
Old 05-19-2010, 08:36 PM   #2 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
Join Date: Jan 2010
Location: Issaquah, WA
Age: 42
Posts: 1,244
dljeffery is on a distinguished road
Default

I like the look. The blog looks interesting, too.

Several thoughts:

1) Don't implement -tableView:heightForRowAtIndexPath: unless you actually have variable-height cells. It doesn't slow you down after the table view loads, but it will definitely slow down the initial loading process (if you have 1,000 rows, this method will get called 1,000 times as part of loading the table view, before anything is ever shown). If this is the view that is shown as soon as the app starts, the OS could even kill the app as a result. You should instead just set the rowHeight property of your table view.

2) It looks like you are downloading relatively large graphics, one per article, just to build your cell, and you're doing it synchronously. This is surely what's slowing you down. Look into using NSURLConnection to download them asynchronously, and just put a placeholder graphic or a spinner (or both) in the cell to start.

3) You don't seem to be caching anything... and I'll bet that each time the app is launched, there will only be a few new records to display. So why not cache old results, at least for the table cells? If the (old) articles actually get edited frequently, then I could see not caching for your detail view, but the cells should still ideally be cached. Also, save a thumbnail sized image to disk for future display (including display during the current session, since it looks to me like if you scroll down several rows, then scroll back up, you'll currently have to download your image all over again...).

4) Scaling images is slow and still takes a ton of memory, in my experience... another reason to create thumbnails of the images for your cells, since you will have several cells loaded at the same time. You might even play around with image quality of the thumbnails to try to minimize memory consumption while still having a nice enough image at the scaled down size.
__________________
Recall It! Tag your notes. Tag your photos. Tag your thoughts. Tag your life.

Recall It! for iPad

http://www.dljeffery.com
dljeffery is offline   Reply With Quote
Old 05-19-2010, 10:30 PM   #3 (permalink)
Registered Member
 
pereorra's Avatar
 
Join Date: Oct 2009
Location: Mataró, Barcelona, Spain
Posts: 14
pereorra is on a distinguished road
Default

Have a look at this tutorial, its great for what you are doing: UITables with Downloaded Images – Easy Asynchronous Code | markjnet
__________________
My Apps:



My Website: www.pereorra.com
pereorra is offline   Reply With Quote
Old 05-19-2010, 10:37 PM   #4 (permalink)
Registered Member
 
Join Date: May 2010
Location: Montreal, QC
Posts: 9
Craftpaper is on a distinguished road
Send a message via Skype™ to Craftpaper
Default

Thanks, I gonna try and let you know the improvements (it will probably be useful for many developers)
Craftpaper is offline   Reply With Quote
Old 05-19-2010, 11:16 PM   #5 (permalink)
Registered Member
 
Join Date: May 2010
Location: Montreal, QC
Posts: 9
Craftpaper is on a distinguished road
Send a message via Skype™ to Craftpaper
Default

Oh yeah, and the pictures I use are 150x150 (Converted from the website then downloaded), I don't use the original one (full size on the website uneparisienneamontreal.com)
Craftpaper is offline   Reply With Quote
Old 05-19-2010, 11:43 PM   #6 (permalink)
Registered Member
 
mobileben's Avatar
 
Join Date: Jul 2009
Location: Zgrunturos
Posts: 161
mobileben is on a distinguished road
Default

dljeffery sort of hit the nail on the head. Esp the part about "caching". Your killer really is image load during cellForRowAtIndexPath.

A great example is the experience you get with online content viewers. These typically have loaded cells in the UITableView. But there is a limit to the number of cells they show you from their "load". You typically select a "Next 20" or something like that.

We have a very lagless UITable view that is custom draw as well as using some small images. Not 150x150. What we do is before we do a reload of the data, we generate, if not already done, all image instances (we only do this once per run time during init). We then generate an array that represents each cell. This array is a set of data structures which contain the image views needed. Since we're doing a custom draw, we really only need to know what array element we're on, and then draw the images.

Your ideal case of UITableView management is doing very little as far as data management when scrolling.
__________________
Have a Poketastic time with QuitIt!
Arcade Basketball at it's best! Hoops Madness!
VS action on the iPad with Hoops Madness VS!
Sweet trailer here!
mobileben is offline   Reply With Quote
Old 05-20-2010, 01:51 AM   #7 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
Join Date: Jan 2010
Location: Issaquah, WA
Age: 42
Posts: 1,244
dljeffery is on a distinguished road
Default

Quote:
Originally Posted by Craftpaper View Post
Oh yeah, and the pictures I use are 150x150 (Converted from the website then downloaded), I don't use the original one (full size on the website uneparisienneamontreal.com)
So since you have a collaborative relationship with the webmaster of the blog, and you are only showing something like an 80x80 (probably actually a bit smaller?) image in your cells, I think the ideal situation here would be to get the webmaster to provide whatever size of image you need, so there is never any need for you to create a thumbnail of the appropriate size.

But you definitely still need to do caching... images certainly, but also text. At least whatever shows up in your table cells.
__________________
Recall It! Tag your notes. Tag your photos. Tag your thoughts. Tag your life.

Recall It! for iPad

http://www.dljeffery.com
dljeffery is offline   Reply With Quote
Old 05-20-2010, 03:04 AM   #8 (permalink)
Registered Member
 
Join Date: Apr 2010
Location: Switzerland
Posts: 12
chrisch is on a distinguished road
Default

As well as making your image request asynchronous, check out this Fast Scrolling in Tweetie with UITableView blog post. I've applied this method and it's made a huge improvement to my tables.
__________________
TrackMyTour - Travel tracking for the iPhone
chrisch is offline   Reply With Quote
Old 08-21-2010, 12:40 PM   #9 (permalink)
Registered Member
 
Join Date: Jul 2010
Posts: 2
mickyang is on a distinguished road
Default

There's a vey good official example here from Apple : LazyTableImages I think you'll find the right approach in there....
mickyang is offline   Reply With Quote
Reply

Bookmarks

Tags
cell, memory, scrolling, uitableview, uitableviewcell

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 307
9 members and 298 guests
Abidullah, ajay123123, Fstuff, guusleijsten, HemiMG, newDev, pkIDSF, Sami Gh, Steven.C
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,648
Threads: 94,113
Posts: 402,877
Top Poster: BrianSlick (7,990)
Welcome to our newest member, brandon6031
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 07:49 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0