setNeedsDisplay не всегда вызывает drawRect - PullRequest
10 голосов
/ 17 мая 2009

У меня есть пользовательское представление в пользовательской ячейке таблицы. Каждый раз, когда конкретное свойство в настраиваемом представлении изменяется, я вызываю [self setNeedsDisplay], который перерисовывает представление в - (void)drawRect:(CGRect)rect. Это свойство установлено в делегате табличного представления tableView:cellForRowAtIndexPath:. Но когда табличное представление больше экрана и ячейки нужно использовать повторно, drawRect не вызывается каждый раз, когда setNeedsDisplay. Особенно когда я быстро щелкаю по столу. Медленная прокрутка работает отлично. Это приводит к тому, что информация в первой и последней ячейках часто неверна.

В журнале видно, что обычно для каждого вызова на setNeedsDisplay происходит вызов на drawRect, но когда я быстро прокручиваю представление таблицы, звонков на setNeedsDisplay больше, чем на drawRect. Конечно, здесь должно быть соотношение один к одному.

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

Кто-нибудь знает, что здесь происходит? Есть ли другой способ заставить собственный вид перерисовать себя?

Ответы [ 4 ]

13 голосов
/ 17 сентября 2009

Я думаю, что боролся с этой проблемой почти неделю, прежде чем нашел проблему. Вот оно, и я не шучу:

Указатель на это пользовательское представление был определен в файле .m вместо файла .h, что делает его переменной класса вместо переменной экземпляра.

И да, я очень, очень смущен.

7 голосов
/ 18 мая 2009

setNeedsDisplay будет вызывать drawRect: только в том случае, если представление является видимым, в противном случае оно делает недействительным слой представления, а drawRect: будет вызываться, когда оно станет видимым.

При прокрутке табличного представления табличное представление будет запрашивать ячейки в надежде добавить их в представление. Если прокрутка выполняется достаточно быстро, некоторым ячейкам потребуется слишком много времени для подготовки, и к тому времени, когда они будут готовы, место, где они должны быть расположены, находится за пределами экрана. В этих случаях табличное представление отбрасывает их, а не добавляет их в представление прокрутки (и, таким образом, drawRect: не будет вызываться)

1 голос
/ 17 мая 2009

Вы должны звонить [_table_ reloadData], чтобы перерисовать таблицу. Не [_table_cell_ setNeedsDsiplay]

0 голосов
/ 18 мая 2009

Похоже, что существует два обстоятельства, при которых представление обновляется: если внутреннее значение изменяется (и вы вызываете [self setNeedsDisplay] для принудительного обновления), а также если табличное представление запрашивает, чтобы ячейка была нарисована (или повторно использована) , Вы явно не перерисовываете это пользовательское представление в этой ситуации.

Согласно документам:

Представитель табличного представления в tableView: cellForRowAtIndexPath: должен всегда сбрасывать все содержимое при повторном использовании ячейки.

Если просмотр таблицы перерабатывает ячейки, он возвращает ячейку со старыми значениями, которые все еще сохраняются. Это зависит от вас, чтобы убедиться, что содержание обновляется. В зависимости от того, как вы настроили свою пользовательскую ячейку таблицы, вам может потребоваться сделать больше, чтобы убедиться, что представление обновлено, но самой простой вещью в обработчике пользовательской ячейки таблицы будет принудительный вызов [myCustomView setNeedsDisplay].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...