Objective-C: Is there any event when a Table Cell goes away?
Is there any message I can override called when a Table Cell goes away (on scrolling the table)?
I think it should be something like dealoc.
I'm asking this because I have below situation: I have a table with many cells (100+) and each of this cell contains a ImageView. For loading the image (from a URL) I'开发者_运维百科m using NSOperationQueue/NSInvocationOperation. The problem appears when user is scrolling the table before the image is completely loaded: because I'm reusing the cells the image is displayed in wrong cell.
To avoid this I'm thinking to use "cancelAllOperations" of NSOperationQueue object when the cell goes away.
Note: I've tried but is not working if I call this message on "prepareForReuse".
iOS 6:
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
// Cancel operation here for cell at indexPath
}
Why not keeping the images in your table data source - the array that holds all the data for the table?
This way you won't have to load these images once again when scrolling back and it will solve your problem...
You can subclass UITableViewCell (or any UIView) and override willMoveToWindow:. It is called whenever the cell appears (or scrolls off screen).
When it goes out of the window the parameter will be nil:
- (void)willMoveToWindow:(UIWindow *)newWindow
{
[super willMoveToWindow:newWindow];
if (newWindow==nil) {
// Cell is no longer in window
}
}
If there were, it would be in the UITableViewDelegate
class reference: http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UITableViewDelegate
The only thing they have is willDisplayCell
which lets you do last minute adjustments BEFORE the cell appears. They don't have anything for when it disappears, but you could probably figure that out since there are only a certain number of cells on the screen at a time for a given cell height.
So if one is appearing and for a cell height of 80 for instance (in portrait mode so 480px screen height), then you can say that the one 6 cells away is about to disappear (6 cells * 80 pixels = 480). There are a couple other things to consider like which way you are scrolling, but you get the general idea.
Example Code: You should also look at lazy table loading via Apple's sample code http://developer.apple.com/iphone/library/samplecode/LazyTableImages/Introduction/Intro.html
I had the same issue and got some nice feedback in the developer forum. Quinn - The Eskimo from Apple:
As an aside, cancelling a network small transfer because something has scrolled off the screen is probably a performance negative. For small transfers, it's usually more efficient to let it run to completion (and cache the results in case they're needed in the future). This is because of the way that NSURLConnection manages HTTP connection reuse. If you cancel a transfer, NSURLConnection has to either a) drop the underlying HTTP connection on the floor, which means it can't be reused, or b) continue reading and just junk the data. Neither of this is the best use of resources.
Share and Enjoy -- Quinn "The Eskimo!"
So, I'm not cancelling all the ImageDownload Operation, but rather only start them, when the user stops scrolling. Up to then only a placeholder is shown:
- (void)scrollViewWillBeginDragging:(UITableView *) tableView
{
self.dragging = TRUE;
}
- (void) scrollViewDidEndDragging: (UITableView *) tableView willDecelerate: (BOOL) decelerate
{
if(!decelerate && self.dragging)
[self loadThumbsForVisibleCells];
else
self.dragging = FALSE;
}
- (void) scrollViewDidEndDecelerating: (UITableView *) tableView
{
[self loadThumbsForVisibleCells];
}
Hope this helps!
精彩评论