Case
Обычно вы должны использовать метод делегата cellForRowAtIndexPath
для настройки вашей ячейки. Информация, заданная для ячейки, важна для того, как будет рисоваться ячейка и каков размер.
К сожалению, метод делегата heightForRowAtIndexPath
вызывается перед методом делегата cellForRowAtIndexPath
, поэтому мы не можем просто сказать делегату вернуть высоту ячейки, так как в это время это будет 0.
Таким образом, нам нужно вычислить размер до того, как ячейка будет нарисована в таблице. К счастью, существует метод, который делает именно это, sizeWithFont
, который принадлежит классу NSString. Однако есть проблема, чтобы динамически вычислять правильный размер, чтобы знать, как будут представлены элементы в ячейке. Я сделаю это в примере:
Представьте себе UITableViewCell
, который содержит метку с именем textLabel
. В рамках метода делегата cellForRowAtIndexPath
мы помещаем textLabel.numberOfLines = 0
, который в основном сообщает ярлыку, что он может иметь столько строк, сколько ему нужно представить текст для определенной ширины. Проблема возникает, если мы придаем textLabel текст, который больше ширины, первоначально заданной для textLabel. Появится вторая строка, но высота ячейки не будет автоматически скорректирована, и мы получим беспорядочный вид таблицы.
Как было сказано ранее, мы можем использовать sizeWithFont
для вычисления высоты, но он должен знать, какой шрифт используется, для какой ширины и т.д. Если по соображениям простоты мы просто заботимся о ширине, мы могли бы жестко кодировать что ширина будет около 320,0 (при этом не учитывается прокладка). Но что произойдет, если мы будем использовать UITableViewStyleGrouped вместо простой ширины, тогда будет около 300,0, и ячейка снова будет испорчена. Или что происходит, если мы переходим от портрета к пейзажу, у нас гораздо больше места, но он не будет использоваться, так как мы жестко закодировали 300.0.
Это тот случай, когда в какой-то момент вы должны задать себе вопрос, насколько вы можете избежать жесткого кодирования.
Мои собственные мысли
Вы можете вызвать метод cellForRowAtIndexPath
, который принадлежит классу UITableView, чтобы получить ячейку для определенного раздела и строки. Я прочитал пару сообщений, в которых говорилось, что вы не хотите этого делать, но я этого не понимаю. Да, я согласен, что он уже выделит ячейку, но метод делегата heightForRowAtIndexPath
вызывается только для ячеек, которые будут видны, поэтому ячейка будет выделена в любом случае. Если вы правильно используете dequeueReusableCellWithIdentifier
, ячейка не будет снова выделена в методе cellForRowAtIndexPath
, вместо этого используется указатель и свойства будут только что настроены. Тогда какая проблема?
Обратите внимание, что ячейка НЕ рисуется внутри метода делегата cellForRowAtIndexPath
, когда ячейка просмотра таблицы становится видимой, script вызывает метод setNeedDisplay
в UITableVieCell, который запускает метод drawRect
для рисования ячейки, Поэтому вызов делегата cellForRowAtIndexPath
напрямую не потеряет производительность, потому что его нужно сделать дважды.
Итак, вызывая метод делегата cellForRowAtIndexPath
в методе делегата heightForRowAtIndexPath
, мы получаем всю необходимую информацию о ячейке для определения ее размера.
Возможно, вы можете создать свой собственный метод sizeForCell
, который проходит через все параметры, что если ячейка находится в стиле Value1 или Value2 и т.д.
Заключение/Вопрос
Это просто теория, которую я описал в своих мыслях, я хотел бы знать, правильно ли я написал. Или, может быть, есть другой способ сделать то же самое. Обратите внимание, что я хочу иметь возможность делать все как можно более гибким.