В настоящее время я изучаю чертеж с UIView и CALayer. Я быстро сделал приложение для рисования, чтобы поэкспериментировать с двумя классами. Я заметил, что CALayer хуже, чем UIView. Вот код:iOS: почему UIView's drawRect имеет лучшую производительность, чем DrawIcontext CALayer
myView.m
@interface myView()
@property (nonatomic, strong) UIImageView *background;
#ifdef USE_LAYER
@property (nonatomic, strong) drawingLayer *drawCanvas;
#else
@property (nonatomic, strong) drawingView *drawCanvas;
#endif
@end
@implementation myView
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
self.background = [[UIImageView alloc] initWithFrame:frame];
[self addSubview:self.background];
#ifdef USE_LAYER
self.drawCanvas = [[drawingLayer alloc] init];
self.drawCanvas.frame = frame;
[self.layer addSublayer:self.drawCanvas];
#else
self.drawCanvas = [[drawingView alloc] initWithFrame:frame];
self.drawCanvas.backgroundColor = [UIColor clearColor];
[self addSubview:self.drawCanvas];
#endif
}
return self;
}
- (CGPoint)getPoint:(NSSet<UITouch *> *)touches
{
NSArray *touchesArray = [touches allObjects];
UITouch *touch = (UITouch *)[touchesArray objectAtIndex:0];
return [touch locationInView:self];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CGPoint point = [self getPoint:touches];
self.drawCanvas.points = [[NSMutableArray alloc] init];
self.drawCanvas.startPoint = point;
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CGPoint point = [self getPoint:touches];
[self.drawCanvas.points addObject:[NSValue valueWithCGPoint:point]];
self.background.image = [self imageFromLayer:self.layer];
self.drawCanvas.points = nil;
[self.drawCanvas setNeedsDisplay];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CGPoint point = [self getPoint:touches];
[self.drawCanvas.points addObject:[NSValue valueWithCGPoint:point]];
[self.drawCanvas setNeedsDisplay];
}
- (UIImage *)imageFromLayer:(CALayer *)layer
{
UIGraphicsBeginImageContext([layer frame].size);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
@end
drawingView.h
@interface drawingView : UIView
@property (nonatomic, assign) CGPoint startPoint;
@property (nonatomic, strong) NSMutableArray *points;
@end
drawingView.m
@implementation drawingView
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 2.0f);
CGContextMoveToPoint(context, self.startPoint.x, self.startPoint.y);
for (NSValue *point in self.points)
{
CGPoint location = [point CGPointValue];
CGContextAddLineToPoint(context, location.x, location.y);
}
CGContextStrokePath(context);
}
@end
У меня также есть "drawingLayer", который, по существу, то же самое как «drawingView», за исключением подкласса CALayer и делает тот же рисунок в «drawInContext».
То, что я нашел, было то, что drawRect имеет намного лучшую производительность, рисунок почти синхронно с положением касания, с очень небольшим отставанием. Почему это так? Я ожидал, что рисунок CALayer будет по крайней мере одинаковым, если не лучше. Фактически, кто-то сказал мне сегодня, что рисование в CALayer аппаратно ускорено, что является предпочтительным способом, если производительность является проблемой. Конечно, это не так в моем маленьком эксперименте. Зачем?
CALayer анимации может сделать вид, медленнее в движении. Возможно, это то, что вы наблюдаете. –
Чувствуете ли вы, что это медленнее, или это действительно так? Вы использовали Инструменты для проверки этого? Кроме того, вы попробовали обновить cgPath CAShapeLayer? Это может повысить производительность. – Lepidopteron