Ответ 1
Довольно часто рисовать все на экране вне экрана и просто отображать это изображение при рисовании экрана. Вы можете прочитать: Создание растрового графического контекста.
Мой оригинальный вопрос:
Я создаю простой рисунок приложения и должны иметь возможность нарисовать существующий ранее выделенный контент в моем
drawRect
. Каков правильный способ использовать поверх существующего контента без его полной замены?
Основываясь на ответах, полученных здесь и в других местах, вот сделка.
Вы должны быть готовы перерисовать
весь прямоугольник всякий раз, когда drawRect
называется.
не может предотвратить стирание содержимого, выполнив следующие действия:
[self setClearsContextBeforeDrawing: NO];
Это всего лишь намек на графический движок, который не имеет смысла в том, чтобы он предварительно очистил представление для вас, так как вам, вероятно, придется снова рисовать всю область. Это может помешать вашему стилю автоматически стираться, , но вы не можете зависеть от него.
Чтобы рисовать поверх вашего представления без стирания, сделайте рисунок в контекстном растровом контексте (который никогда не очищается системой.) Затем в drawRect
копируйте этот буфер вне экрана к виду.
Пример:
- (id) initWithCoder: (NSCoder*) coder {
if (self = [super initWithCoder: coder]) {
self.backgroundColor = [UIColor clearColor];
CGSize size = self.frame.size;
drawingContext = [self createDrawingBufferContext: size];
}
return self;
}
- (CGContextRef) createOffscreenContext: (CGSize) size {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, size.width*4, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
CGContextTranslateCTM(context, 0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);
return context;
}
- (void)drawRect:(CGRect) rect {
UIGraphicsPushContext(drawingContext);
CGImageRef cgImage = CGBitmapContextCreateImage(drawingContext);
UIImage *uiImage = [[UIImage alloc] initWithCGImage:cgImage];
UIGraphicsPopContext();
CGImageRelease(cgImage);
[uiImage drawInRect: rect];
[uiImage release];
}
TODO: может ли кто-нибудь оптимизировать drawRect
, чтобы для копии использовалась только (обычно маленькая) область прямоугольника?
Довольно часто рисовать все на экране вне экрана и просто отображать это изображение при рисовании экрана. Вы можете прочитать: Создание растрового графического контекста.
Оптимизация drawRect
Попробуйте следующее:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGImageRef cgImage = CGBitmapContextCreateImage(drawingContext);
CGContextClipToRect(context, rect);
CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), cgImage);
CGImageRelease(cgImage);
}
После этого вы также должны прокомментировать эти строки в своем коде:
//CGContextTranslateCTM(context, 0, size.height);
//CGContextScaleCTM(context, 1.0, -1.0);
Также создан отдельный вопрос, чтобы убедиться, что это оптимальный способ.
Это похоже на лучший метод, чем я использовал. То есть, в случае касания я делаю копию представления, которое должно быть обновлено. Затем в drawRect я беру это изображение и рисую его в представление и одновременно изменяю свои другие представления.
Но это кажется неэффективным, но единственным способом я понял, как это сделать.
Это предотвратит стирание вашего представления до выполнения drawRect:
[self.layer setNeedsDisplay];
Кроме того, я считаю, что лучше всего сделать весь чертеж в методе drawRect (если у вас нет веской причины). Рисование за кадром и передача занимает больше времени и добавляет больше сложности, а затем просто рисует все раз.