UITableViewCell по-прежнему показывает изображение, перекрывающее текст после очистки

#iphone #cocoa-touch #uitableview

#iPhone #cocoa-touch #uitableview

Вопрос:

У меня есть, UITableViewController который отображает кучу ‘n’ строк (все с использованием стандартного UITableViewCell класса), последняя из которых имеет изображение (маленький значок ‘ ‘, чтобы указать ‘Добавить запись’).

Предположим, что следующий сценарий:

  1. Пользователь нажимает на эту последнюю строку, которая помещает новый контроллер представления в стек навигации
  2. Затем пользователь заполняет форму для добавления новой записи, которая сохраняется с использованием Core Data
  3. Затем форма извлекается из стека навигации, возвращая вас к этому первому UITableViewController , и я вызываю [self.tableView reloadData] , чтобы убедиться, что отображается новое состояние

Теперь вы видите ‘n 1’ строк, последняя из которых теперь показывает изображение ‘ ‘. Проблема в том, что я столкнулся с ошибкой, из-за которой в строке ‘n’ по-прежнему отображается изображение ‘ ‘, за исключением того, что оно перекрывается с текстовой меткой для этой ячейки (я мог понять ошибку, из-за которой показывалось изображение ‘ ‘ слева от текста — я явно установил imageView.image = nil , чтобы избежать этого — но тот факт, что изображение перекрывается с текстом, делает это действительно странным).

Вот код для моей cellForRowAtIndexPath функции:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = @"Cell";
    UITableViewCellStyle cellStyle;

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

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    if ((self.selectedCategory != nil) amp;amp; (indexPath.row < [self.selectedCategory.subjects count])) {
        Subject *managedObject = (Subject*)[self.selectedCatSubjects objectAtIndex:indexPath.row];
        cell.textLabel.text = managedObject.name;
        cell.imageView.image = nil; // Needed in case there used to be a " " icon
    } else {
        cell.textLabel.text = @"Add subject...";
        [cell.imageView initWithImage:_addIcon]; 
    }

    return cell;
}
  

Комментарии:

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

2. замените NSString *cellIdentifier = @»Cell»; на NSString *cellIdentifier = [NSString stringWithFormat:@»Cell%d%d»,indexPath.section,indexPath.row];

3. @Krishnabhadra Я думаю, что это немного снижает смысл повторного использования ячеек в первую очередь, не так ли? метод @7KV7 звучит как менее излишний

4. @andygeers, конечно, это неправильный способ.. Вот почему я поместил это в качестве комментария.. Я просто хочу знать, что у вас все еще та же проблема после использования другого идентификатора ячейки.. Честно говоря, я не думаю, что это ваша проблема..

5. @7KV7 Ах!! У меня получилось! Я пробовал подход @Krishnabhadra с использованием индекса раздела и строки в качестве идентификатора, но это не помогает, потому что индекс строки остается неизменным даже при изменении использования ячейки. Если я явно изменю его на что-то вроде «PlusCell» для последней строки, то это исправит ошибку. Не могли бы вы опубликовать это как правильный ответ, чтобы я мог проголосовать за него и принять его?

Ответ №1:

Попробуйте использовать другой идентификатор для последней строки:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = @"Cell";
    UITableViewCellStyle cellStyle;

    BOOL isFinalRow = (self.selectedCategory == nil) || (indexPath.row >= [self.selectedCategory.subjects count]);
    if (isFinalRow) {
        CellIdentifier = @"AddCell";
    }

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

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    if (!isFinalRow) {
        Subject *managedObject = (Subject*)[self.selectedCatSubjects objectAtIndex:indexPath.row];
        cell.textLabel.text = managedObject.name;
        cell.imageView.image = nil; // Needed in case there used to be a " " icon
    } else {
        cell.textLabel.text = @"Add subject...";
        [cell.imageView initWithImage:_addIcon]; 
    }

    return cell;
}
  

Комментарии:

1. Есть ли предположение, что существует проблема со встроенными представлениями изображений и, следовательно, вы внедряете свои собственные?

2. @andygeers вы пробовали использовать точки останова? При повторном использовании n-й строки вы попадаете в свое условие if.

3. сделайте одну вещь, попробуйте скрыть imageview вместо того, чтобы указывать nil ..cell.ImageView.hidden = true;

4. @Krishnabhadra Я не пробовал это, но я думаю, что это должно быть иначе текст не перекрывал бы изображение, он был бы с отступом, как в n 1-й строке.

5. @Krishnabhadra Я только что попробовал hidden = true и это не помогает : (Хотя хорошая идея!

Ответ №2:

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

 if(indexPath.row==[self.selectedCategory.subjects count]) 
{
cellIdentifier = @"PlusCell";
}
  

Ответ №3:

У меня это сработало.

заменить :

 static NSString *CellIdentifier = @"Cell";
  

в

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

с :

 NSString *CellIdentifier = [NSString stringWithFormat:@"%d_%d",indexPath.section,indexPath.row];
  

Комментарии:

1. Это довольно неэффективно, если у вас нет очень веской причины для этого — вы теряете все преимущества повторного использования ячеек. Принятый ответ выполняет свою работу — потому что отличается только последняя ячейка, и поэтому только последней ячейке требуется другой идентификатор

2. @andygeers я не думаю, что это неэффективно, потому что лучше установить уникальный идентификатор для каждой ячейки, а не проверять ячейку с условием if else. однако существует несколько ячеек разного типа.