2014-01-28 4 views
0

У меня есть подкласс UITableViewCell, который имеет изображение, название и описание. Я должен изменить размер ячейки в соответствии с длиной содержимого описания, т. Е. Если он охватывает более 5 строк, я должен расширить его (+ другие подовые изображения, такие как изображение и т. Д.), Пока он не будет продолжаться.Как настроить пользовательский UITableViewCell с разной высотой

Следующие ближайшие ячейки должны начинаться только после этого.

У меня есть UITableViewCell подкласса экземпляр из XIb, который имеет фиксированную высоту строки = 160.

Я знаю, что это довольно стандартное требование, но я не могу найти какие-либо рекомендации.

I уже продлевал layoutSubViews, как это:

- (void) layoutSubviews 
{ 
    [self resizeCellImage]; 
} 

- (void) resizeCellImage 
{ 
    CGRect descriptionRect = self.cellDescriptionLabel.frame; 
    CGRect imageRect = self.cellImageView.frame; 

    float descriptionBottomEdgeY = descriptionRect.origin.y + descriptionRect.size.height; 
    float imageBottomEdgeY = imageRect.origin.y + imageRect.size.height; 

    if (imageBottomEdgeY >= descriptionBottomEdgeY) 
     return; 

    //push the bottom of image to the bottom of description 
    imageBottomEdgeY = descriptionBottomEdgeY; 

    float newImageHeight = imageBottomEdgeY - imageRect.origin.y; 
    imageRect.size.height = newImageHeight; 
    self.cellImageView.frame = imageRect; 

    CGRect cellFrame = self.frame; 
    cellFrame.size.height = imageRect.size.height + imageRect.origin.y + 5; 

    CGRect contentFrame = self.contentView.frame; 
    contentFrame.size.height = cellFrame.size.height - 1; 
    self.contentView.frame = contentFrame; 

    self.frame = cellFrame; 
} 

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

Однако, когда я вызываю этот код, как это сделать:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    cell.cellDescriptionLabel.text = @"Some long string"; 
    [cell.cellDescriptionLabel sizeToFit]; 
    [cell setNeedsLayout]; 

    return cell;  
} 

Оказывается, что в то время как клетки кадра изменяется из-за layoutSubViews вызова, другие клетки не уважают его. То есть, они появляются в том же положении, если предыдущая ячейка не изменила бы сама по себе.

Два вопроса:

  • Как сделать возможным то, что я хочу?
  • Имею ли я право по телефону setNeedsLayout в пределах cellForRowAtIndexPath?

P.S .: Я знаю, что heightForRowAtIndexPath имеет ключевое значение для изменения высоты ячейки, но я чувствую, что данные синтаксический анализ (не показанные здесь), что я делаю, как часть cellForRowAtIndexPath были бы излишество просто вычислить высоту. Мне нужно что-то, что может прямо сообщить UITableViewCell, чтобы изменить размер в соответствии с потребностями контента.

+0

Вы можете выполнить синтаксический анализ данных в 'heightForRowAtIndexPath', а затем повторно использовать его в' cellForRowAtIndexPath'. – nemesis

+0

Хорошая мысль, однако должен быть способ сказать самой ячейке, что вот содержание для вас, и вы сами изменяете размер, что и происходит в cellForRowAtIndexPath - правильный способ чтения в ячейку. Я знаю, что есть способы, но мне просто нужно это открыть. –

+1

Хотел бы я помочь, но на самом деле я понятия не имею. Но я бы хотел увидеть ответ, когда вы его решаете, так что, удачи! :) – nemesis

ответ

3

-tableView:heightForRowAtIndexPath: - это дизайн, в котором рассчитываются ячейки переменного размера. Фактический кадр ячейки не имеет значения и изменен табличным представлением в соответствии с его потребностями.

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

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


UPDATE: Как получить Клеточные Heights

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

@property (nonatomic) MyTableViewCell *standInCell; 

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

@property (nonatomic) CGFloat standInCellBaseHeight; 

Тогда в -tableView:heightForRowAtIndexPath: я получить высоту для всех моих переменных размеров взглядов с фактическими данными для этого индекса пути. Я добавляю высоту с переменным размером на мой стенд в базовой высоте ячейки. Я возвращаю эту новую расчетную высоту.

Обратите внимание, что все это не автоспуск. Я уверен, что подход будет похож, но не идентичен этому, но у меня нет опыта.

+0

Правда, но тогда как получить доступ к ячейке в tableView: heightForRowAtIndexPath, кроме вызова cellForRowAtIndexPath? И если я это сделаю, я бы сделал дополнительный вызов cellForRowAtIndexPath, который уже вызван reloadData. Плюс мой рост зависит от контента, поэтому в основном я буду переделывать вещи в обеих функциях. –

+0

@NiravBhatt Я обновил свой ответ. –

1

-tableView:heightForRowAtIndexPath: - это предпочтительный способ рассказать о табло вид его ячеек. Вы можете либо предварительно просчитать и кешировать его в словаре, либо повторно использовать, либо, в качестве альтернативы, в ios7, вы можете использовать -tableView:estimatedHeightForRowAtIndexPath: для оценки размеров.

1

Взгляните на эту тему - https://stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-variable-row-heights, ответ указывает на очень хороший пример проекта здесь - https://github.com/caoimghgin/TableViewCellWithAutoLayout.

Извините, но, насколько мне известно, вы должны реализовать tableView:heightForRowAtIndexPath:. Предупреждение, в iOS 6 это вызывает сразу каждую строку в UITableView, я думаю, чтобы нарисовать полосу прокрутки. iOS7 вводит tableView:estimatedHeightForRowAtIndexPath:, который, если он реализован, позволяет просто догадываться о высоте перед выполнением всех вычислений. Это может многое помочь на очень больших таблицах.

То, что я нашел хорошо работает только иметь свой tableView:heightForRowAtIndexPath: вызов cellForRowAtIndexPath: получить ячейку для этой строки, а затем запросить эту ячейку для его высоты cell.bounds.size.height и вернуть это.

Это хорошо работает для небольших столов или в iOS7 с использованием tableView:estimatedHeightForRowAtIndexPath.

+0

Разве это не вызовет двойной вызов cellForRowAtIndexPath? И куда поместить данные, которые я делаю как часть cellForRowAtIndexPath прямо сейчас? –

+0

Да, это мой вопрос. Вам нужно либо вычислить свою высоту независимо от ячейки, либо просто использовать ячейку. Если у вас сумасшедшая ячейка, использующая автозапуск, и вам будет сложно узнать высоту, но только 10 из них, то я бы сказал, что двойной удар стоит того. Но если у вас есть более 1000 ячеек, тогда может быть целесообразно выполнить работу, чтобы определить высоту без рендеринга ячейки. Вы также можете посмотреть в кеширование. Я нашел, что это зависит от вашей ситуации. Мне не нравится, как Apple разбила их на два, в отличие от WPF, которые будут получать высоту из контейнера. – ansible

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