3

I have an annoying problem with displaying UITableViewCell with UIActivityIndicatorView inside. My tableView delegate loads portions of data. The last cell always indicates loading process while new portion is not loaded. Loading starts in tableView: willDisplayCell: forRowAtIndexPath:.So in iOS 5 (or iOS 5 simulator) it works perfectly, but in iOS 6 (or iOS 6 simulator) UIActivityIndicatorView displays only for the first time. Maybe something was deprecated since iOS 6 or it's iOS 6 bug?

Here is my dataSource:

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    UITableViewCell* cell = nil;
    if (_callback != nil && !_noMoreBooks && indexPath.row == [_books count])
    {
        cell = [tableView dequeueReusableCellWithIdentifier:LTTableViewLoadMoreCellIdentifier];
        if (cell == nil)
        {
            cell = [[[LTLoadMoreCell alloc] initWithStyle:UITableViewCellStyleDefault
                                          reuseIdentifier:LTTableViewLoadMoreCellIdentifier] autorelease];
            [(LTLoadMoreCell*)cell setRowTag:-1];
        }
    }
    else
    {
        cell = [tableView dequeueReusableCellWithIdentifier:LTTableViewCellIdentifier];
        if (cell == nil)
        {
            cell = [[[LTBookCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:LTTableViewCellIdentifier] autorelease];
            cell.selectionStyle = UITableViewCellSelectionStyleGray;
            ((LTBookCell*)cell)._hidePrice = NO;
        }
    }
    return cell;
}

Here's my delegate:

- (void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCell*)cell forRowAtIndexPath:(NSIndexPath*)indexPath
{
    if ([LTTableViewLoadMoreCellIdentifier isEqualToString:[cell reuseIdentifier]]
        && [(LTLoadMoreCell*)cell rowTag] != indexPath.row)
    {
        [(LTLoadMoreCell*)cell setRowTag:indexPath.row];
        NSUInteger remain = LT_STORE_BOOK_LIST_LIMIT - rowsLoaded;
        NSUInteger by = remain < LT_STORE_BOOKS_LOAD_PORTION ? remain : LT_STORE_BOOKS_LOAD_PORTION;
        _currentError = _callback(_genres, rowsLoaded, by);
        if (_currentError == LTNoInternetError)
        {
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
        }
        else if (_currentError != LTErrorNone)
        {
            _noMoreBooks = YES;
        }
    }
    else if ([LTTableViewCellIdentifier isEqualToString:[cell reuseIdentifier]])
    {
        if ((indexPath.row == rowsLoaded-1) && _currentError == LTNoInternetError)
        {
            NSUInteger remain = LT_STORE_BOOK_LIST_LIMIT - rowsLoaded;
            NSUInteger by = remain < LT_STORE_BOOKS_LOAD_PORTION ? remain : LT_STORE_BOOKS_LOAD_PORTION;
            _currentError = _callback(_genres, rowsLoaded, by);
            if (_currentError == LTErrorNone)
                [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewScrollPositionBottom];
        }
        LTBook* rowBook = [_books extraObjectAtIndex:indexPath.row];
        if (rowBook != nil)
        {
            ((LTBookCell*)cell)._book = rowBook;
            ((LTBookCell*)cell).isOdd = (indexPath.row % 2);
        }
    }
}

And this is LoadMoreCell.m:

#import "LTLoadMoreCell.h"

@implementation LTLoadMoreCell

@synthesize rowTag;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    if (self)
    {
        _activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        [_activityIndicatorView startAnimating];
        [[self contentView] addSubview:_activityIndicatorView];
        [self setUserInteractionEnabled:NO];
    }

    return self;
}

- (void)dealloc
{
    [_activityIndicatorView release];
    [super dealloc];
}

#pragma mark -
#pragma mark *** UITableViewCell methods ***
#pragma mark -

- (void)layoutSubviews
{
    [super layoutSubviews];
    [_activityIndicatorView setAutoresizingMask:UIViewAutoresizingNone];
    CGSize cellSize = [[self contentView] frame].size;
    [_activityIndicatorView setCenter:CGPointMake(cellSize.width / 2, cellSize.height / 2)];
}

@end
4

2 回答 2

5

Apparently animation stops in some moment, i don't understand why this happens only in iOS 6. So I removed [_activityIndicatorView startAnimating]; from init method and added to layoutSubviews this:

if(![_activityIndicatorView isAnimating])
       [_activityIndicatorView startAnimating];

I think it's iOS 6 bug.

于 2012-11-15T11:21:31.327 回答
2

you call [activyView startAnimating] in your cell's INIT method only.. try calling it before you want it to animate :: willDisplayCell or even viewForCell

于 2012-11-15T09:53:40.603 回答