iOS xcode, добавление подвида UILabel в настраиваемую ячейку таблицы, текст метки не обновляется на экране

Я создал собственный класс UITableViewCell и использовал метод layoutSubviews для добавления пользовательской метки. Так:

- (void)layoutSubviews
{
    [super layoutSubviews];

    if (statusLabel == nil)
    {
        statusLabel = [[UILabel alloc]initWithFrame:CGRectMake(430.0, 10.0, 100.0, 20.0)];
        [statusLabel setTextAlignment:UITextAlignmentRight];
        [statusLabel setText:@"Status, set in code"];
        statusLabel.tag = 1;

        [self.contentView addSubview:statusLabel];
    }        
}

Как видите, я установил исходный текст метки на «Статус, установленный в коде».

В контроллере табличного представления я устанавливаю текст для этой пользовательской метки в методе cellForRowAtIndexPath, например:

- (UITableViewCell *)tableView:(UITableView *)tableView
     cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    int index = [indexPath row];

    NSString *introducerString =[introducers objectAtIndex:index];
        NSArray *parts = [introducerString componentsSeparatedByString:@","];

    static NSString *MyIdentifier = @"Requester";
    UITableViewCell *cell = [tableView
                             dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) 
    {
        cell = [[[DanceCardCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                       reuseIdentifier:MyIdentifier] autorelease];
    }

    UIImage *image = [UIImage imageNamed:@"1.jpg"];
    [cell.imageView setImage:image];
    cell.textLabel.text = [parts objectAtIndex:1];
    cell.detailTextLabel.text = @"Some text";

    UILabel *statusLabel = (UILabel *)[cell viewWithTag:1];
    statusLabel.text = @"Did it!";

    return cell;
}

Я использую одно табличное представление для отображения двух списков, в зависимости от того, какая из двух кнопок нажата. При нажатии кнопки соответствующий контроллер табличного представления присоединяется к табличному представлению, и вызывается метод reloadData для запуска отображения новых данных. Новые данные действительно отображаются, но текст пользовательской метки, который должен читаться «Сделано это!» читает «Статус, установленный в коде ...», пока я снова не переключаю списки дважды.

Как я могу сразу обновить новый текст для пользовательской метки? Я проверил официальную документацию и не могу найти никаких упоминаний об обновлении отображения ячейки после обновления ее пользовательского содержимого.

Вот снимок экрана, демонстрирующий, что происходит: http://www.dsbsystems.co.uk/images/xcode1.png


person David Bridge    schedule 13.09.2011    source источник


Ответы (1)


Вы инициализируете ячейку и сразу же пытаетесь найти внутри нее statusLabel с тегом 1. layoutSubviews еще не было возможности быть вызванным, поэтому метка не была создана и добавлена. (Я предлагаю переопределить назначенный метод инициализации в ячейке табличного представления и создать там метку.)

Из-за этого при попытке вытащить statusLabel он становится nil, потому что такого представления нет, а обмен сообщениями (вызов метода на) nil просто ничего не делает (фактически возвращает nil). Вам нужно будет следить за этим в будущем, если вы привыкли к тому, что вещи взрываются, например. исключения нулевой ссылки.

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

person Jesper    schedule 13.09.2011
comment
Спасибо. Идея ленивой инициализации представлений неплохая, но лучше всего она работает, когда применяется к большим представлениям. Когда ячейка создана, вы знаете, что вам сразу же понадобится метка. - person Jesper; 13.09.2011