UITableView гибкий/динамичный heightForRowAtIndexPath

Случай

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

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

Таким образом, мы должны вычислить размер, прежде чем ячейка будет оттянута в таблице. К счастью существует метод, который делает просто это, sizeWithFont, который принадлежит классу NSString. Однако существует проблема для вычисления корректного размера динамично, это должно знать, как элементы в ячейке будут представлены. Я ясно дам понять это в примере:

Вообразите a UITableViewCell, который содержит названную маркировку textLabel. В cellForRowAtIndexPath метод делегата мы помещаем textLabel.numberOfLines = 0, который в основном говорит маркировке, что она может иметь столько строк, сколько она должна представить текст для определенной ширины. Проблема происходит, если мы даем textLabel текст, больше затем ширина, первоначально данная textLabel. Вторая строка появится, но высота ячейки не будет автоматически регулироваться и таким образом, мы получим испорченное выглядящее табличное представление.

Как сказано ранее, мы можем использовать sizeWithFont для вычисления высоты но это должно знать, какой Шрифт используется, поскольку что ширина, и т.д. Если бы по причинам простоты мы просто заботимся о ширине, мы могли hardcode, что ширина была бы приблизительно 320,0 (не берущий дополняющий в соображении). Но что произошло бы, если бы мы использовали UITableViewStyleGrouped вместо плоскости, то ширина затем была бы приблизительно 300,0, и ячейка была бы снова испорчена. Или что happends, если мы подкачиваем от портрета до среды, у нас есть намного больше пространства, все же это не будет использоваться так как мы hardcoded 300.0.

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

Мои собственные мысли

Вы могли звонить cellForRowAtIndexPath метод, который принадлежит классу UITableView для получения ячейки для определенного раздела и строки. Я читал несколько сообщений, в которых было сказано, что Вы не хотите делать это, но я действительно не понимаю это. Да, я соглашаюсь, что это уже выделит ячейку, но heightForRowAtIndexPath метод делегата только называют для ячеек, которые будут видимы, таким образом, ячейка будет выделена так или иначе. Если Вы правильно используете dequeueReusableCellWithIdentifier ячейка не будет выделена снова в cellForRowAtIndexPath метод, вместо этого указатель используется, и свойства просто корректируются. Затем, какова проблема?

Обратите внимание, что ячейка НЕ оттянута в cellForRowAtIndexPath метод делегата, когда ячейка табличного представления станет видимой сценарий, будет звонить setNeedDisplay метод на UITableVieCell, который инициировал drawRect метод для рисования ячейки. Так вызов cellForRowAtIndexPath делегат непосредственно не потеряет производительность, потому что она должна быть оттянута дважды.

Хорошо так путем вызова cellForRowAtIndexPath метод делегата в heightForRowAtIndexPath метод делегата мы получаем всю информацию, мы должны о ячейке решить, что это - размер.

Возможно, можно создать собственное sizeForCell метод, который пробегает все опции, что, если ячейка находится в стиле Value1 или Value2, и т.д.

Заключение/Вопрос

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

60
задан tshepang 6 July 2014 в 16:23
поделиться

2 ответа

Вам следует взглянуть на TTTableItemCell.m во фреймворке Three20. Он следует другому подходу, в основном за счет того, что каждый класс ячеек (с некоторыми предопределенными настройками, такими как шрифт, макет и т. Д.) Реализует общий метод + tableView: sizeForItem: (или что-то в этом роде), куда он передается текст в объекте item. Когда вы ищете текст для определенной ячейки, вы также можете найти соответствующий шрифт.

Что касается высоты ячейки: вы можете проверить ширину вашего tableView и, при необходимости, вычесть поля на UITableViewStyleGrouped и ширину конечной панели индекса и элемента раскрытия (который вы ищете в хранилище данных для данные ваших ячеек). Когда ширина tableView изменяется, например при ротации интерфейса необходимо вызвать [tableView reloadData] .

4
ответ дан 24 November 2019 в 17:54
поделиться

Я делал это путем:

  1. создания объектов коллекции (массив информации о размере (словарь, NSNumber высоты строк и т.д.) на основе объектов коллекции, которые будут использоваться в табличном представлении.

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

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

  4. Эти объекты коллекции будут использоваться каждый раз, когда я внедряю протоколы UITableViewDataSource или UITableViewDelegate для определения размеров экземпляров UITableViewCell, их субпросмотров и т.д.

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

Не используйте абсолютное значение для инициализации кадров. Используйте относительное значение, основанное на текущей ориентации и границах.

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

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

8
ответ дан 24 November 2019 в 17:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: