Когда создается UITableView, и всякий раз, когда вы отправляете ему сообщение reloadData, источнику данных отправляется одно сообщение heightForRowAtIndexPath для каждой ячейки.Поэтому, если в вашей таблице 30 ячеек, это сообщение отправляется 30 раз.
Скажем, на экране видны только шесть из этих 30 ячеек.В этом случае при создании и при отправке ему сообщения reloadData UITableView будет отправлять одно сообщение cellForRowAtIndexPath на видимую строку, то есть это сообщение отправляется шесть раз.
Почему Apple реализует его так?Частично причина в том, что почти всегда дешевле вычислить высоту строки, чем построить и заполнить целую ячейку.И учитывая, что во многих таблицах высота каждой ячейки будет одинаковой, она зачастую значительно дешевле.И отчасти причина в том, что iOS нужно знать размер всей таблицы: это позволяет ей создавать полосы прокрутки и настраивать их в представлении прокрутки и т. Д.
Если высота строк варьируется по размеру, потому чтоони содержат различное количество текста, вы можете использовать один из методов sizeWithFont: в соответствующей строке для выполнения вычислений.Это быстрее, чем создание представления и последующее измерение результата.Обратите внимание, что если вы измените высоту ячейки, вам нужно будет либо перезагрузить всю таблицу (с помощью reloadData - это будет запрашивать у делегата каждую высоту, но только запрашивать видимые ячейки) ИЛИ выборочно перезагружать строки, где размер имеетизменено.
Дополнительный материал Если я понимаю следующий вопрос в комментарии, может помочь следующее:
Если вы используете режим редактирования, то это не редкостьнужно изменить высоту строк таблицы.Например, у вас может быть текст в строках таблицы, и когда их ячейки сужаются - чтобы освободить место для удаляемых кругов справа - вы можете захотеть, чтобы некоторые ячейки стали выше для размещения текста.Основной подход здесь заключается в следующем:
Убедитесь, что tableView: heightForRowAtIndexPath: метод знает, находитесь ли вы в режиме редактирования или нет.(Он может запросить tableView с помощью isEditing.) И затем получить метод, который возвращает правильную высоту, в зависимости от того, находитесь ли вы в режиме редактирования или нет.
В вашем setEditing: animated:Метод в UITableViewController (или UIViewController, в зависимости от того, что вы используете - есть некоторые различия в зависимости от того, что вы используете, поэтому стоит тщательно проверить документацию), отправив сообщение reloadData в tableView после изменения его состояния.Это заставит tableView захватывать высоты каждой строки, и он будет заново выбирать ячейки для видимых строк.TableView обрабатывает сужение ячеек при входе в режим редактирования, но если вы хотите больше работать с макетом, сделайте это в tableView: cellForRowAtIndex :.Как отмечалось выше, общая стратегия состоит в том, чтобы найти способ быстрого расчета высоты.С размером текстаWithFont: (и его варианты) может сделать это.Если у вас есть изображения и т. Д., То вы можете взять их размеры и сделать некоторые суммы.
В дополнение к этим шагам вы можете также захотеть немного прокрутить tableView после переключения режимов.Если высота ваших строк различна, то после переключения вы окажетесь в неверной позиции в таблице.Подход, который я здесь выбрал, заключается в использовании executeSelector: withObject: afterDelay после перезагрузки таблицы для вызова метода, который выполняет настройку прокрутки.Вам нужно использовать задержку, чтобы дать возможность tableView собрать новые высоты и новые ячейки таблицы.(Возможно, есть более разумный способ сделать это.) Я делаю некоторые суммы, чтобы выполнить настройку прокрутки на основе разницы между origin.y tableView: cellForRowAtIndexPath: первой видимой строки ячейки на экране до и после перезагрузки.Так, например, чтобы получить позицию до предварительной загрузки, что-то вроде этого.
CGPoint offset = [[self tableView] contentOffset];
NSIndexPath* indexPath = [[self tableView] indexPathForRowAtPoint:CGPointMake(0,offset.y)];
CGFloat preCellOffset = [[[self tableView] cellForRowAtIndexPath:indexPath] origin].y;