gpt4 book ai didi

iOS:为什么UIView的drawRect比CALayer的drawInContext有更好的性能

转载 作者:行者123 更新时间:2023-12-01 16:28:11 24 4
gpt4 key购买 nike

我目前正在学习使用 UIView 和 CALayer 绘图。我很快做了一个绘图应用程序来试验这两个类。我注意到 CALayer 的性能比 UIView 差。这是代码:

我的 View .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

绘图 View .h

@interface drawingView : UIView

@property (nonatomic, assign) CGPoint startPoint;
@property (nonatomic, strong) NSMutableArray *points;

@end

绘图 View .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的默认动画导致的

尝试覆盖 action(forKey event: String) -> CAAction? 并在子类化 CALayer 类时始终返回 nil

关于iOS:为什么UIView的drawRect比CALayer的drawInContext有更好的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34019830/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com