Отрегулируйте высоту tableviewcell на основе содержимого

Я создаю приложение, похожее на facebook. И я хочу настроить высоту ячейки в зависимости от содержимого. Ячейка tableview состоит из UIImageView, UILabel и UIButton. Я могу настроить высоту ячейки с помощью делегата heightForRowAtIndexPath, но бывает, что в определенной ячейке нет изображения.

Насколько я знаю, сначала звонили heightForRowAtIndexPath. Итак, я не могу передать высоту объекта, рассчитанную в cellForRowAtIndexPath.

Я хочу знать, могу ли я передать высоту объекта в heightForRowAtIndexPath внутри cellForRowAtIndexPath.


person user3300758    schedule 24.07.2014    source источник


Ответы (4)


Обычно высота предварительного просмотра изображения в ячейке фиксирована. И вы можете рассчитать высоту ячейки в heightForRowAtIndexPath.

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

Или вы можете сначала загрузить изображение и получить высоту из UImage.

Обычно я использую второй или первый случай в своих приложениях.

person AlKozin    schedule 24.07.2014

Правильное решение:

Добавьте @property (strong, nonatomic) MyCell* prototypeCell; в контроллер.

Создайте геттер:

- (MyCell*) prototypeCell {
  if (!_prototypeCell) {
    _prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:@"MyCell"];
  }

 return _prototypeCell;
}

Переместите весь код, связанный с конфигурацией ячейки, из cellForRow в класс Cell (вы можете посмотреть здесь: Как получить доступ к свойствам в нескольких пользовательских tableviewcells)

Изменить высоту для строки:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
  return size.height+1;   
}

Работает с автомакетом. Если у вас не включена авторазметка - можно посчитать вручную.

Для повышения производительности на iOS7 используйте:

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return 300; // or any number based on your estimation
}
person Nikita Took    schedule 24.07.2014

heightForRowAtIndexPath вызывается первым. Именно здесь вы должны проверить, имеет ли ячейка в этом конкретном indexPath изображение, и соответственно установить высоту. Вы не предоставили никакого кода. Но если у вас есть массив объектов с изображением и строками, необходимыми для заполнения tableView, код должен выглядеть примерно так:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CustomObject *object = (CustomObject *)[arrayOfObjects objectAtIndex:indexPath.row];
    if (object.cellImage != null) {
        return 60; //height for row that has image;
    }
    return 44; //those without image
}
person Harikrishnan    schedule 24.07.2014

Нет, вы не можете, это быстрый ответ.

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

Начиная с iOS8 таблица сможет использовать Autolayout для получения высоты ячейки — см. Что нового в представлениях таблиц и коллекций с WWDC 2014.

person jrturton    schedule 24.07.2014