Является ли drawRect () просто крючком для выполнения вашего кода рисования?
Он предназначен для перерисовки области (прямоугольника), которая передается вам, используя текущий стек графического контекста. Не более.
Или этот метод должен также перерисовывать области, которые "повреждены" и нуждаются в перерисовке?
Нет. Если грязные регионы не пересекаются, вы можете получить несколько вызовов drawRect:
с различными передаваемыми вам ректами. Rects признаны недействительными, используя setNeedsDisplayInRect:
. Если необходимо перерисовать только часть поверхности вашего вида, вам будет предложено нарисовать эту часть, когда придет время рисовать.
Могу ли я просто нарисовать свои вещи один раз, а потом они "залипают", или я должен перекрасить всю сцену в любое время с помощью drawRect ()?
Он не «прилипает». Rects становятся недействительными во время выполнения вашего приложения, и вас просят перерисовать эти reect, когда системе представления необходимо обновить экран. Вы перекрашиваете только тот прямоугольник, который запрашивается.
В некоторых случаях простая реализация может (довольно лениво) лишать законной силы весь прямоугольник представления всякий раз, когда часть становится недействительной. Как правило, это плохо, потому что обычно требуется больше рисунка, чем необходимо, и особенно расточительно, когда виды не непрозрачны.
Java-объект Graphics2D работает таким образом - вы должны рисовать все свое «изображение» каждый раз, когда вызывается paint (), поэтому вы должны быть готовы к его восстановлению в любое время (или кешированию).
Не так с AppKit или UIKit.
Как бы вы реализовали простую программу для рисования? Придется ли вам «запоминать» каждую линию / точку / обводку, которую рисовал пользователь, и повторять это каждый раз, когда вызывается drawRect ()?
Вы должны будете помнить контекст (например, каждую линию / точку / штрих), необходимый для рисования вашего вида. Вам нужно только нарисовать регион, который запрашивается. Технически графическая система не будет жаловаться, если вы будете рисовать за пределами этого прямоугольника, но это может привести к артефактам.
Для сложного рендеринга может быть проще или эффективнее нарисовать во внешнем буфере (например, растровом изображении), а затем использовать это предварительно представленное растровое представление, чтобы получить изображение на экране в drawrect:
. (см. также ответ Брэда для слоев)
Как насчет "закадрового" рендеринга? Вы можете сделать все свои рисунки, а затем вызвать [self setNeedsDisplay], чтобы ваши записи были сброшены на экран?
Да, вы можете сделать это. В частности, вы должны выполнить рендеринг во внешний буфер (например, растровое изображение), когда вы закончите рендеринг в растровое изображение, сделаете недействительным прямоугольник, который вы хотите нарисовать, а затем начнете рисовать на экране, используя данные в растровом изображении при вызове drawRect:
.
Допустим, в ответ на прикосновение пользователя я хочу поставить «Х» на экране, где он коснулся. Х должен оставаться там, и каждое новое касание создает еще один Х. Нужно ли мне помнить все эти координаты касания и затем рисовать их все в drawRect ()?
Ну, у вас есть несколько вариантов. Ваше предложение одно (при условии, что вы рисуете в переданном вам прямоугольнике). Другой способ - создать представление «X» и просто запомнить точки, необходимые для восстановления представления, если вам нужно, чтобы эти X сохранялись при запусках. Во многих случаях вы можете легко разделить сложные задачи на слои (простая 2D игра):
- 1) Фоновое изображение с горизонтом.
- 2) Некоторые вещи на переднем плане, которые меняются не часто.
- 3) Персонаж, которого игрок использует для навигации по игре.
Итак, большинство проблем можно легко разделить, поэтому вам не нужно все время рендерить. Это снижает сложность и улучшает производительность, если все сделано хорошо. Если сделано плохо, это может быть несколько намного хуже.