iPhone: добавление подпредставлений в Cell ContentView перезаписывает тексты ячеек при прокрутке - PullRequest
3 голосов
/ 16 июня 2011

Я использовал Cell.ContentView в своей реализации для настройки содержимого ячейки. Это работает нормально, но единственная проблема в том, что когда у меня много ячеек, и я прокручиваю их вверх и вниз, содержимое ячеек перезаписывается в ячейки, которые просто становятся скрытыми, а затем видимыми. Предположим, что я прокручиваю первую ячейку вверх, а затем снова снимаю ее, содержимое последней ячейки перезаписывается в первой ячейке !!

Я достаточно отлажен, но не смог найти точное решение. Я попытался проверить количество Cell.ContentView.SubViews и, если оно 0, добавить только другие подпредставления. Это не отображает содержимое ячеек, пока я не прокручиваю их вверх и вниз, но как только содержимое появилось, оно не перезаписывается .. Немного странно ... !! Я также убедился, что я использую правильное повторное использование клетки. Ниже приведен мой код, который добавляет подпредставления в представление содержимого ячейки. Пожалуйста, дайте мне знать, как я могу избавиться от этой проблемы.

P.S .: Не беспокойтесь о переменных и вычислениях, которые я сделал. Предположим, что он возвращает правильные значения. :)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    NSInteger totalAvailableSpace = IPHONE_DISPLAY_WIDTH - iconSize - accesorySize - 10;
    NSInteger lableHeight = [[cellDetails objectForKey:@"TableItemTextFontSize"] intValue] * 2 + 10;

    UILabel *textLabel = nil;
    textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+12, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.8, lableHeight)] autorelease];
    textLabel.numberOfLines = 2;
    textLabel.lineBreakMode = UILineBreakModeWordWrap;
    textLabel.textAlignment = UITextAlignmentLeft;
    textLabel.text = [cellDetails objectForKey:@"TableItemMainText"];
    if ([textLableColor scanHexInt:&hex]) {
        textLabel.textColor = UIColorFromRGB(hex);
    }
    textLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemTextFontName"] size:[[cellDetails objectForKey:@"TableItemTextFontSize"] intValue]]; 
    [cell.contentView addSubview:textLabel];
    textLabel.backgroundColor = [UIColor clearColor];

    lableHeight = [[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue] * 2 + 10;
    UILabel *detailTextLabel = nil;
    detailTextLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+10+totalAvailableSpace * 0.8+5, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.2 - 10, lableHeight)] autorelease];
    detailTextLabel.numberOfLines = 2;
    detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
    detailTextLabel.textAlignment = UITextAlignmentLeft;
    detailTextLabel.text = [cellDetails objectForKey:@"TableItemDetailText"];
    if ([detailTextLableColor scanHexInt:&hex]) {
        detailTextLabel.textColor = UIColorFromRGB(hex);
    }
    detailTextLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemDetailTextFontName"] size:[[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue]];
    [cell.contentView addSubview:detailTextLabel];
    detailTextLabel.backgroundColor = [UIColor clearColor];

    return cell;
}

Спасибо.

Ответы [ 5 ]

6 голосов
/ 16 июня 2011

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

Вы должны добавлять их только при создании ячейки и устанавливать метки только при повторном использовании ячейки.

Вы можете установить теги для вашего ярлыка, чтобы потом можно было установить его текст. Код ниже делает трюк

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        if(style == UITableViewCellStyleValue1)
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        else
            cell = [[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:CellIdentifier] autorelease];


        NSInteger totalAvailableSpace = IPHONE_DISPLAY_WIDTH - iconSize - accesorySize - 10;
        NSInteger lableHeight = [[cellDetails objectForKey:@"TableItemTextFontSize"] intValue] * 2 + 10;

        UILabel *textLabel = nil;
        textLabel.tag = 1;
        textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+12, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.8, lableHeight)] autorelease];
        textLabel.numberOfLines = 2;
        textLabel.lineBreakMode = UILineBreakModeWordWrap;
        textLabel.textAlignment = UITextAlignmentLeft;
        textLabel.text = [cellDetails objectForKey:@"TableItemMainText"];
        if ([textLableColor scanHexInt:&hex]) {
            textLabel.textColor = UIColorFromRGB(hex);
        }
        textLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemTextFontName"] size:[[cellDetails objectForKey:@"TableItemTextFontSize"] intValue]]; 
        [cell.contentView addSubview:textLabel];
        textLabel.backgroundColor = [UIColor clearColor];

        lableHeight = [[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue] * 2 + 10;
        UILabel *detailTextLabel = nil;
        detailTextLabel.tag = 2;
        detailTextLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+10+totalAvailableSpace * 0.8+5, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.2 - 10, lableHeight)] autorelease];
        detailTextLabel.numberOfLines = 2;
        detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
        detailTextLabel.textAlignment = UITextAlignmentLeft;
        detailTextLabel.text = [cellDetails objectForKey:@"TableItemDetailText"];
        if ([detailTextLableColor scanHexInt:&hex]) {
            detailTextLabel.textColor = UIColorFromRGB(hex);
        }
        detailTextLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemDetailTextFontName"] size:[[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue]];
        [cell.contentView addSubview:detailTextLabel];
        detailTextLabel.backgroundColor = [UIColor clearColor];

    } else {

        UILabel *textLabel = (UILabel *)[cell viewWithTag:1];
        textLabel.text = [cellDetails objectForKey:@"TableItemMainText"];

        UILabel *detailTextLabel = (UILabel *)[cell viewWithTag:2];
        detailTextLabel.text = [cellDetails objectForKey:@"TableItemDetailText"];

    }

    return cell;
}
4 голосов
/ 03 октября 2012
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];

if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}

Убедитесь, что dequeueReusableCellWithIdentifier и reuseIdentifier должны быть nil

Теперь это будет работать !!

2 голосов
/ 16 июня 2011

Для ясности, ваша проблема в том, что когда вы прокручиваете видимую ячейку, вы часто будете сталкиваться с текстом новой ячейки, записываемой поверх ячейки, которая была только что прокручена за пределами экрана?

Проблема в том, что dequeueReusableCellWithIdentifier: не "очищает" ячейку (она вызывает prepareForReuse, но это все), поэтому все ваши старые подпредставления все еще на месте. Если вы собираетесь повторно использовать ячейки, вам не следует каждый раз воссоздавать эти подпредставления. Вместо этого просто настройте свойства существующих подпредставлений в ячейке, которую вы вернули из dequeueReusableCellWithIdentifier:, и создавайте только новые подпредставления в только что выделенной ячейке. Подклассы UITableViewCell могут помочь в этом как для предоставления свойств / ivars, в которых можно хранить ссылки на эти подпредставления, так и для организации более приятного кода путем перемещения создания подпредставлений и обновления в соответствующие методы. Или вы можете просто не использовать ячейки повторно, передав nil для идентификатора повторного использования.

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

2 голосов
/ 16 июня 2011

Поместите все содержимое пользовательского интерфейса в ячейку if (cell == nil) {uilabel, uilabel или что-нибудь связанное с UI} ... так как пользовательский интерфейс должен вызываться только один раз во время создания cel

0 голосов
/ 26 июня 2013

В iOS5 UILineBreakModeWordWrap устарело.Вместо этого вы должны использовать NSLineBreakByWordWrapping.

Это изменит ваш код, чтобы он выглядел как detailTextLabel.lineBreakMode = NSLineBreakByWordWrapping и textLabel.lineBreakMode = NSLineBreakByWordWrapping.

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