views:

338

answers:

4

Hi everyone, I'm developing on the iPhone and I have seen in the AppStore that the images are progressively downloaded in the UITableView... How can I implement that? My idea was to detect the showed content (which cells are shown) and download these images. My problem is that I don't know how to detect the showed cells! Is it the good way to do it?

Best

+3  A: 

The way this was demonstrated at the iPhone Developer Tech Talk was to use NSOperation and NSOperationQueue.

The idea is to wrap up your image download request (using NSURLRequest) into an NSOperation.

You can set your cell as the receiver of a call back sent by your operation when it's complete so that you can attach the image to the cell (draw it manually, or add it to an image view).

Then basically, in your cellForRowAtIndexPath method, tell the cell to start the image download, and have the cell create an NSOperation and add it to the operation queue managed by your table view controller or something.

The queue will start executing the operations and call back to each cell when they're done.

If you want to, you can cancel the operation if the cell moves offscreen, so you don't waste resources downloading an image that will be thrown away because the cell won't be visible to display the image.

Jasarien
my problem is how I detect the cells which are displayed?
ncohen
A cell is displayed after the `tableView:cellForRowAtIndexPath:` method is called, since that's the method that provides the table view with the cell to display.In your cell subclass, have a method that creates an NSOperation that encapsulates an image download, and add it to an NSOperationQueue managed by your table view controller or somewhere else in your app.
Jasarien
when I say display, I mean visible on the screen... If you look at the appstore, it is only when the scroll view did scroll that the images are downloaded! How can I detect the displayed cells?
ncohen
Like I said. When a cell is to be displayed on the screen, `tableView:cellForRowAtIndexPath:` is called. That method is called when and only when a cell is needed to be displayed on the screen. You use this method to know when a cell is displayed on the screen. Cells are reused, so when the table view is loaded for the first time, this method is called for each cell that is needed to be displayed initially, and then once for each cell that is scrolled on screen subsequently. When a cell is needed to be displayed a subsequent time after being displayed and is being reused, this method is called
Jasarien
ok I will try that... thx
ncohen
A: 

@Jasarien: nice answer

Or you can use the three20 project if you want. there is a TTTableViewController that already handles all the stuff you want. you only have to input the URL to the imageview and viola.

TT also caches your images in memory or also on disk.

check out the sample project bundled in three20 gitbub ressource. there an example.

choise
Thanks but I've already done the big part... don't want to restart!
ncohen
Three20 is great, if you plan to use a lot of what it offers, but because everything to do with Three20 is so tightly coupled to the TTStyle stuff, it brings a lot of overhead if you only want to use one or two features.
Jasarien
+1  A: 
corprew
thank you but still have the problem of knowing which cell is visible on the screen!
ncohen
That's a great extension to UIImageView (wish I thought of that myself ;)) but it's quite a different approach to the NSOperation method I described. This is excellent for use with UIImageViews, but in some cases, especially where you want cells that scroll very quickly, using a UIImageView can cause too much of a performance drag by having a rich View hierarchy. In those cases it makes more sense to use a multithreaded approach.
Jasarien
A: 

I would implement each cell as a subclass of UITableViewCell and then override willMoveToWindow: method in the subclass. willMoveToWindow: is called when the cell view becomes visible on the screen or when it goes off screen (newWindow gets nil). Then each cell can queue a request to load its image as it becomes visible (and maybe even cancel its queued request if it goes off screen).

BTW, You can use the visibleCells property of UITableView to get the list of cells that are visible.

progrmr
Thx visibleCell was exactly what I was looking for!
ncohen