setNeedsDisplay используется для повторного рендеринга или повторного рисования представления (экземпляр подкласса UIView или UIView). С нашей точки зрения: он вызывает drawRect:, но на самом деле перед этим подготавливает контекст и делает вид готовым к перерисовке. (Вот почему вам не следует вызывать drawRect: напрямую)
Обычный случай, когда вы реализовали метод drawRect: (некоторые примеры: отрисовка содержимого с помощью OpenGL в представлении или отрисовка текста с использованием CoreText или отрисовка некоторой графики с использованием CoreGraphics и т. д.), если вы хотите обновить рисунок в определенный момент, вы явно вызываете setNeedsDisplay, и он вызовет функцию drawRect:, и ваш вид сразу же будет перерисован. Если нет, метод drawRect: будет вызываться при изменении границ представления и в некоторых других ситуациях, когда система решит, что необходимо перерисовать представление.
В случае кнопки вам не нужно этого делать, потому что, конечно, когда кнопка нажата, будет выполнен внутренний вызов setNeedsDisplay, заставляющий кнопку измениться и т. д. (Кто действительно знает, что происходит в фоновом режиме. Дело вам не нужно беспокоиться о drawRect: при использовании UIButtons таким образом)
Вы также можете изменить внешний вид вида, перемещая его подслои или подвиды, и это не обязательно означает перерисовку вида. Это тот случай, когда вы действуете как контейнер, а не как объект рисования.
Хорошим правилом может быть то, что вам не нужно явно вызывать setNeedsDisplay, если вы не реализовали метод drawRect:.
http://developer.apple.com/iphone/library/documentation/uikit/reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/drawRect:
Надеюсь, поможет.
;)
ОБНОВЛЕНИЕ: 09.09.2009
то, как UIButton вызывает drawRect: зависит от его реализации, и мы не должны заботиться об этом (по крайней мере, если мы не создаем подклассы). Но если вы действительно это знаете, вы можете создать подкласс и переопределить:
- (void) drawRect:(CGRect)frame{
NSLog(@"%s is being called!!!", _cmd);
[super drawRect:frame];
}
а теперь из другого объекта попробуйте загрузить его, изменить его размер, переместить, прокрутить (если доступно), скрыть его и увидеть консоль отладки (Cmd + Shift + R). Я бы рекомендовал сделать это не только для UIButton, но и для обычный UIView. Это наверняка даст четкое представление о том, когда вызывается drawRect:. ;) (Также другие методы, такие как layoutSubviews: и т. д.)
Причина, по которой я сказал, что мы не должны заботиться о drawRect: в UIButton, заключается в том, что он нам не нужен, мы устанавливаем изображение для определенного состояния, используя setImage: forState: и все. Мы можем переустановить эти изображения в любое время, и кнопка изменит свое изображение по мере необходимости, и она может перерисовать свой вид в зависимости от того, как ее разработали инженеры Apple.
Что касается вашего вопроса, соответствует ли setNeedsDisplay правилу, которое я вам дал. Я верю, что да. Я поставил точку останова в начале каждого метода и ничего и проверил, что происходит, когда вызывается setNeedsDisplay. Ни один из методов LeverView не вызывался!. затем я прокомментировал 3 вызова setNeedsDisplay, и результаты были такими же! (iOS4.1) Следовательно, эти три строки кода не нужны. ;)
Вы должны быть осторожны при вызове setNeedsDisplay, потому что в зависимости от вашей реализации это может сделать вашу программу очень медленной! так как собирается все перерисовывать и наверное не надо. ;)
Фууу... лол. Довольно длинный пост только про drawRect:
Ваше здоровье
person
nacho4d
schedule
08.09.2010