开发者

UITableView cell just disappeared callback?

I have a UITableView with heavy images content. So the scrolling is not fluid anymore. I want to add a timer to load the images, while you scroll I create the timer for each row. If the cell quits the view, I cancel the timer. If not I fade in the images.

My question is : is there a callback for a cell going out of view ? I'm reading the doc, but I'm not sure there is anything for my needs.

Thanks for the help !

EDIT: The code I'm using (this is the three20 library, I'm using a custom TTTableItemCell. The "_tabBar1.tabItems = item.photos" is the line hoging resources. On the first load it's okay because the photos are being loaded asynchronously from the server, but when I scroll back or reload the view, they are all loaded synchronously, and the scrolling isn't smooth anymore, especially on an iPhone 3G. :

- (void)setObject:(id)object {
    if (_item != object) {
        [super setObject:object];

        Mission* item = object;

        self.textLabel.text = item.name;
        _tabBar1.tabItems = nil;

        timerFeats = [NSTimer scheduledTimerWithTimeInterval:(0.5f) target:self sel开发者_Go百科ector:@selector(updateFeats) userInfo:nil repeats: NO];  
        //_tabBar1.tabItems = item.photos;
  }
}

-(void)updateFeats {
    DLog(@"timer ended");
    Mission* item = self.object;
    self._tabBar1.tabItems = item.photos;
}


If you're using iOS 6 and up, simply override this method:

- tableView:didEndDisplayingCell:forRowAtIndexPath:

It'll be called when the cell has already gone out of the view, and you'll get it and its indexPath.


Alright, I found a way.

There is actually a callback to know what cell is about to get out of view. :

- (void)willMoveToSuperview:(UIView *)newSuperview;

So my code is :

- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];
    if(!newSuperview) {
        DLog(@"timer invalidated");
        if ([timerFeats isValid]) {
          [timerFeats invalidate];
        }

    }
}

If there is no newSuperview the cell is going out of the view and so I verify first that my timer hasn't been invalidated yet, and then I cancel it.


I suggest to use a KVO approach:

On your awakeFromNib method (or whatever method you use to instantiate the cell) add the following:

- (void)awakeFromNib {
    [self addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionNew context:nil];

    ...
}

Be sure to implement the delegate method for the observer as follow:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if([keyPath isEqualToString:@"hidden"]) {
        NSLog(@"cell is hidden");
    }
}


When a UITableView is initially shown it calls this method once for each row

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath

after this the method is called when ever a new row is required which is often the result of scrolling to reveal a new row and pushing an old view off the other end.

So this is an ideal hook to find out which rows are visible. To check which cells are visible you can call

- (NSArray *)indexPathsForVisibleRows

Because the tableview is the only thing holding a reference to your cells before they are recycled or freshly creaetd you can not get a handle on those timers. What I suggest is creating an NSMutableDictionary ivar and when you create your cells add the timer to the NSMutableDictionary

[timersForIndexs setObject:yourTimer forKey:indexPath];

Now when you recieve - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath you need to do something like

 NSMutableDictionary *tmpDictionary = [timersForIndexs copy];

 [tmpDictionary removeObjectsForKeys:[self.tableView indexPathsForVisibleRows]];

 NSArray *timers = [tmpDictionary allKeys];

 [timers makeObjectsPerformSelector:@selector(invalidate)];

I'm not in front of xcode so this is dry coded so please let me know if you have any problems

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜