Проблема с повторным использованием UITableViewCell's - PullRequest
1 голос
/ 28 мая 2010

У меня есть UITableView, который повторно использует ячейки, когда пользователь прокручивает.Все отображается и прокручивается нормально, кроме случаев, когда пользователь нажимает на фактическую строку, выделенная ячейка отображает некоторый текст из другой ячейки.Я не совсем уверен, почему.

#define IMAGE_TAG 1111
#define LOGIN_TAG 2222
#define FULL_NAME_TAG 3333

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    STUser *mySTUser = [[[STUser alloc]init]autorelease];
    mySTUser = [items objectAtIndex:indexPath.row];

    AsyncImageView* asyncImage = nil;
    UILabel* loginLabel = nil;
    UILabel* fullNameLabel = nil;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }
    else {
        asyncImage = (AsyncImageView *) [cell.contentView viewWithTag:IMAGE_TAG];
        loginLabel = (UILabel *) [cell.contentView viewWithTag:LOGIN_TAG];
        fullNameLabel = (UILabel *) [cell.contentView viewWithTag:FULL_NAME_TAG];
    }

    // Configure the cell...

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    CGRect frame = CGRectMake(0, 0, 44, 44);
    asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
    asyncImage.tag = IMAGE_TAG;
    NSURL* url = [NSURL URLWithString:mySTUser.avatar_url_large];
    [asyncImage loadImageFromURL:url];
    [cell.contentView addSubview:asyncImage];

    loginLabel.tag = LOGIN_TAG;
    CGRect loginLabelFrame = CGRectMake(60, 0, 200, 10);
    loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];
    loginLabel.text = [NSString stringWithFormat:@"%@",mySTUser.login];
    [cell.contentView addSubview:loginLabel];

    fullNameLabel.tag = FULL_NAME_TAG;
    CGRect fullNameLabelFrame = CGRectMake(60, 20, 200, 10);
    fullNameLabel = [[[UILabel alloc] initWithFrame:fullNameLabelFrame] autorelease];
    fullNameLabel.text = [NSString stringWithFormat:@"%@ %@",mySTUser.first_name, mySTUser.last_name]; //[NSString stringWithFormat:@"%@",mySTUser.login];
    [cell.contentView addSubview:fullNameLabel];    


    return cell;
}

Ответы [ 2 ]

6 голосов
/ 28 мая 2010

Эта строка выделяет объект, затем отбрасывает его. Не выделяйте предмет, который вы не будете использовать.

STUser *mySTUser = [[[STUser alloc]init]autorelease];
mySTUser = [items objectAtIndex:indexPath.row];

Вместо этого просто объявите переменную и используйте ее.

STUser *mySTUser;
mySTUser = [items objectAtIndex:indexPath.row];

Эта строка создает новый объект и присваивает его ячейке, но это происходит каждый раз, когда ячейка используется.

asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
[cell.contentView addSubview:asyncImage];

Вместо этого поместите все строки addSubview в условие if, где создается ячейка.

if (cell == nil) {
    CGRect frame = CGRectMake(0, 0, 44, 44);
    CGRect loginLabelFrame = CGRectMake(60, 0, 200, 10);
    CGRect fullNameLabelFrame = CGRectMake(60, 20, 200, 10);
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
    [cell.contentView addSubview:asyncImage];
    loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];
    [cell.contentView addSubview:loginLabel];
    fullNameLabel = [[[UILabel alloc] initWithFrame:fullNameLabelFrame] autorelease];
    [cell.contentView addSubview:fullNameLabel];    
    asyncImage.tag = IMAGE_TAG;
    loginLabel.tag = LOGIN_TAG;
    fullNameLabel.tag = FULL_NAME_TAG;
} else ...

Единственное, что должно происходить вне этого, если блок - это присвоения свойствам, которые меняются в каждой ячейке, например [asyncImage loadImageFromURL:url];, и присвоение текста меткам.

Эта строка присваивает свойство возможно нулевому объекту, а затем выделяет объект.

loginLabel.tag = LOGIN_TAG;
loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];

Вместо этого назначьте свойство после создания объекта.

loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];
loginLabel.tag = LOGIN_TAG;

В этой строке используется отформатированная строка, в которой можно выполнить простое присваивание.

loginLabel.text = [NSString stringWithFormat:@"%@",mySTUser.login];

Вместо этого, предполагая mySTUser.login, просто назначьте его напрямую.

loginLabel.text = mySTUser.login;
0 голосов
/ 28 мая 2010

Если ячейка не равна нулю, вы сначала назначаете изображение и метки в ячейке, а затем снова запускаете их. Правильно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...