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