Как сохранить предыдущий рисунок при использовании Quartz на iPhone? - PullRequest
0 голосов
/ 28 сентября 2010

Я хочу нарисовать на iPhone простую линию, касаясь экрана и перетаскивая его. Мне удалось сделать это, создав подкласс UIView и изменив метод drawRect: по умолчанию. В то же время в моем viewcontroller я обнаруживаю сенсорное событие и при необходимости вызываю [myView setNeedsDisplay]. Проблема в том, что когда я пытаюсь нарисовать вторую линию, предыдущая линия исчезает. Есть ли способ сохранить предыдущую строку на экране?

Любой вклад будет очень признателен.

Ответы [ 2 ]

4 голосов
/ 29 сентября 2010

Обычный метод - использовать CGBitmapContextCreate (). Создайте его в -init / -init-WithFrame: / etc и вызовите CGContextRelease () в -dealloc. Я не уверен, как вы справляетесь с 2-кратным масштабом «отображения сетчатки» с помощью CGBitmapContextCreate ().

(UIGraphicsBeginImageContext () проще, но это может быть небезопасно для UIGraphicsBeginImageContext(); myContext = CFRetain(UIGraphicsGetCurrentContext()); UIGraphicsEndImageContext();.)

Тогда сделайте что-то вроде

#import <QuartzCore/CALayer.h>

-(void)displayLayer:(CALayer*)layer
{
  UIGraphicsPushContext(mycontext);
  ... Update the bitmap context by drawing a line...
  UIGraphicsPopContext();
  CGImageRef cgImage = CGBitmapContextCreateImage(mycontext);
  layer.contents = (id)cgImage;
  CFRelease(cgImage);
}

Я использовал -displayLayer: (функция делегата CALayer; UIView - делегат его слоя) вместо -drawRect: для эффективности: если вы используете -drawRect:, CALayer создает второй контекст ( и, таким образом, вторая копия растрового изображения).


Кроме того, вам может повезти с CGLayer. Я никогда не видел причины использовать его вместо контекста растрового изображения; может быть более эффективным в некоторых случаях.


В качестве альтернативы, вы могли бы сбежать с настройкой self.clearsContextBeforeDrawing = NO, , но это очень вероятно сломает . UIKit (или, точнее, CoreAnimation) ожидает, что вы нарисуете весь вид, содержащийся в прямоугольнике клипа (это аргумент "rect" -drawRect:; он не обязательно будет границей). Если ваше представление выходит за пределы экрана, CoreAnimation может решить, что он хочет вернуть память. Или CoreAnimation может рисовать только ту часть экрана, которая отображается на экране. Или CoreAnimation может выполнять рисование с двойной буферизацией, в результате чего ваш вид будет переключаться между двумя состояниями.

0 голосов
/ 28 сентября 2010

Если вы используете drawRect: для рисования, то вам нужно нарисовать всю область.Таким образом, вам нужно хранить не только данные для последней части, но и все.

В качестве альтернативы вы можете рисовать непосредственно в растровое изображение или генерировать динамические подпредставления для ваших линий (имеет смысл только для очень ограниченного рисования (то есть несколько векторов)

...