2013-07-16 4 views
5

Допустим, что у меня естьИспользование dequeueReusableCellWithIdentifier для пользовательских ячеек

- (UITableViewCell*)tableView:(UITableView*) cellForRowAtIndexPath:(NSIndexPath*)indexPath 
{ 
    static NSString *cellID = @"Cell Identifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 

    if (!cell) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 
    else 
    { 
     return cell; 
    } 

    UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 15, box.size.width, 19.0f)]; 
    nameLabel.text = name; 
    [nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]]; 
    [nameLabel setFont: [UIFont fontWithName: @"HelveticaNeue-Bold" size: 18.0f]]; 
    [nameLabel setBackgroundColor: [UIColor clearColor]]; 
    nameLabel.textAlignment = NSTextAlignmentCenter; 
    [cell addSubview: nameLabel]; 
} 

Что это будет делать?

Если ячейка не нуль, и, допустим, вы находитесь в строке 5, она вернет ячейку для строки 5 с точными текстовыми метками и т. Д.?

В основном, мой вопрос в том, что у вас есть пользовательские ячейки с метками, изображениями и т. Д. Как вы используете cellForRowAtIndexPath с dequeueReusableCellWithIdentifier?

+0

это то же самое для tableviewcell, независимо от того, является ли оно обычным или нет. Вы получаете объект ячейки и перезагружаете все его состояния, а затем добавляете свой контент. Так что да, вам нужно будет очистить содержимое в ярлыках/изображениях (установив его на нуль) и предоставить новый контент. – rydgaze

+1

В этом коде нет способа повторно получить доступ к объекту UILabel, кроме как путем перечисления подсмотров ячейки, которая довольно уродлива. Лучше использовать подкласс UITableViewCell, обладающий свойством UILabel, так что он легко доступен. –

ответ

0

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

Создайте подкласс UITableViewCell, назовем его MyTableViewCell, у которого есть свойства, содержащие метки/imageViews/etc, которые ему понадобятся. После того, как вы отключили или выделили init из одного из MyTableViewCell, вы можете установить текст/изображения/etc в этих свойствах. Например:

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

    static NSString *CellIdentifier = @"identifier"; 

    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
     cell = [[MyTableViewCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:CellIdentifier]; 
    } 



    cell.nameLabel.text = name; 
    cell.imageView.image = anImage; 


    return cell; 
} 

Одна из основных проблем с вашим методом - это условные условия, связанные с деактивацией и созданием. В вашем методе вы только настроили ячейку ярлык, когда она была инициализирована alloc (вы немедленно возвращаете выделенную ячейку без ее форматирования). Однако вы хотите, чтобы эта настройка выполнялась как для выделенных, так и для вручную созданных объектов. Обратите внимание, как это происходит в моем методе, оператор return находится в самом низу. Это гарантирует, что как созданные, так и повторно используемые ячейки имеют соответствующие данные.

РЕДАКТИРОВАТЬ: Одна из важных вещей, которые я забыл, вы создадите свойства своей ячейки в своем методе initWithStyle: reuseIdentifier: и добавьте их как подпункты в ячейку. Это происходит, когда вы отправляете текст метки (или что-то еще) в свой метод cellForRowAtIndexPath, он уже создан. В принципе, ячейка управляет созданием собственных представлений, и делегат UITableView должен беспокоиться о заполнении этих представлений данными.

3

Вы пытаетесь удалить ячейку. Если попытка не удалась (ячейка равна нулю), вы создаете ячейку и настраиваете ее в виде представлений (а не данных внутри представления). После этого вы заполняете представления любыми данными или настройками, которые меняют ячейку. Кроме того, вы должны добавить любые пользовательские представления к ячейке contentView, а не к самой ячейке.

#define NAME_LABEL_TAG 1234 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *cellID = @"Cell Identifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 

    if (!cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 15, box.size.width, 19.0f)]; 
     nameLabel.tag = NAME_LABEL_TAG; 
     [nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]]; 
     [nameLabel setFont: [UIFont fontWithName: @"HelveticaNeue-Bold" size: 18.0f]]; 
     [nameLabel setBackgroundColor: [UIColor clearColor]]; 
     nameLabel.textAlignment = NSTextAlignmentCenter; 
     [cell.contentView addSubview: nameLabel]; 
    } 

    // Populate views with data and retrieve data for "name" variable 
    UILabel *nameLabel = (UILabel *)[cell.contentView viewWithTag:NAME_LABEL_TAG]; 
    nameLabel.text = name; 

    // Return fully configured and populated cell 
    return cell; 
} 

Если у вас есть сложные клетки, часто проще создать его в Interface Builder и подкласса UITableViewCell, так что вы можете иметь дополнительные свойства, которые относятся к вашей метки, кнопки и т.д.

+10

Вы должны знать, что если вы сделаете свою ячейку в раскадровке, dequeueReusableCellWithIdentifier: гарантированно вернет ячейку, поэтому предложение if (! Cell) будет никогда не запускайте. – rdelmar

+0

можно назвать nameLabel.text = name; хотя nameLabel не ссылался, когда ячейка не равна нулю. –

+0

nameLabel будет вне области действия '' if (! Cell) '. Вы должны использовать viewWithTag для получения метки. –

0

UITableView сначала спросить вы за количество ожидаемых ячеек. Затем он загружается через - tableView: cellForRowAtIndexPath: ячейки метода, которые будут отображаться + некоторые, чтобы сгладить прокрутку, больше объектов, которые он не создает. Созданные объекты (по пользователю), хранящиеся в виде таблицы, и вы можете получить доступ к нему не используя метод dequeueReusableCellWithIdentifier :. TableView запрашивает у пользователя изменение существующих созданных ячеек при прокрутке. Если здесь свободный объект - возьмите его из dequeueReusableCellWithIdentifier: другой - создайте новый.

0

, чтобы не выделять каждую ячейку таблицы, таблица выделяет только то, что необходимо. Если на странице помещается только 8 ячеек, тогда в представлении таблицы будет выделено только 8 ячеек или 9, я не помню, имеет ли это дополнение. Когда вы просматриваете табличное представление, и ячейка уходит со страницы, ячейка помещается в очередь для повторного использования, вместо того, чтобы перераспределять новую ячейку, представление таблицы принимает существующий, этот процесс называется dequeue-ing.Когда вы делаете/выделяете свои ячейки, вы даете ему идентификатор, этот идентификатор используется для извлечения ячейки, помеченной этой строкой.

0

Вы можете использовать этот

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath 

Это доступно после прошивки 6

Или вы также можете зарегистрировать свой класс где-то в ViewDidLoad и использовать ResuseIdentifier, так что вам не придется писать ResuseIdentifier часть в CellForRowAtIndexpath

- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0) 

Надеется, что это помогает ...

 Смежные вопросы

  • Нет связанных вопросов^_^