我正在尝试在我的应用程序中使用CAShapeLayer
遮罩 a ,因为它需要一小部分来遮罩图像而不是手动遮罩 a 中的图像;CALayer
iOS
CPU time
bitmap context
当我有几十个或更多图像相互叠加时,CAShapeLayer
蒙版UIImageView
移动到我的触摸时很慢。
这是一些示例代码:
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"SomeImage.jpg" ofType:nil]];
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, NULL, CGRectMake(0.f, 0.f, image.size.width * .25, image.size.height * .25));
for (int i = 0; i < 200; i++) {
SLTUIImageView *imageView = [[SLTUIImageView alloc]initWithImage:image];
imageView.frame = CGRectMake(arc4random_uniform(CGRectGetWidth(self.view.bounds)), arc4random_uniform(CGRectGetHeight(self.view.bounds)), image.size.width * .25, image.size.height * .25);
CAShapeLayer *shape = [CAShapeLayer layer];
shape.path = path;
imageView.layer.mask = shape;
[self.view addSubview:imageView];
[imageView release];
}
CGPathRelease(path);
用上面的代码,imageView
很卡顿。但是,如果我在 a 中手动屏蔽它,它会立即做出反应bitmap context
:
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"3.0-Pad-Classic0.jpg" ofType:nil]];
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, NULL, CGRectMake(0.f, 0.f, image.size.width * .25, image.size.height * .25));
for (int i = 0; i < 200; i++) {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(image.size.width * .25, image.size.height * .25), NO, [[UIScreen mainScreen]scale]);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddPath(ctx, path);
CGContextClip(ctx);
[image drawInRect:CGRectMake(-(image.size.width * .25), -(image.size.height * .25), image.size.width, image.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
SLTUIImageView *imageView = [[SLTUIImageView alloc]initWithImage:finalImage];
imageView.frame = CGRectMake(arc4random_uniform(CGRectGetWidth(self.view.bounds)), arc4random_uniform(CGRectGetHeight(self.view.bounds)), finalImage.size.width, finalImage.size.height);
[self.view addSubview:imageView];
[imageView release];
}
CGPathRelease(path);
顺便说一句,这是 的代码SLTUIImageView
,它只是UIImageView
响应触摸的一个简单子类(对于任何想知道的人):
-(id)initWithImage:(UIImage *)image{
self = [super initWithImage:image];
if (self) {
self.userInteractionEnabled = YES;
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.superview bringSubviewToFront:self];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
self.center = [touch locationInView:self.superview];
}
是否有可能以某种方式优化CAShapeLayer
掩蔽的方式UIImageView
以提高性能?我试图找出瓶颈在哪里使用Time Profiler
in Instruments
,但我无法确切说明是什么原因造成的。
我已经尝试同时设置shouldRasterize
和YES
设置layer
,layer.mask
但似乎都没有任何效果。我不知道该怎么办。
编辑:
我做了更多的测试,发现如果我只使用一个普通CALayer
的来掩盖另一个CALayer (layer.mask = someOtherLayer)
我有同样的性能问题。似乎问题不是特定于 -CAShapeLayer
而是特定mask
于CALayer
.
编辑2:
因此,在了解了有关使用Core Animation tool
in的更多信息后Instruments
,我了解到视图每次移动时都会呈现在屏幕外。设置shouldRaster
为YES
触摸开始时并在触摸结束时关闭它会使视图保持绿色(从而保持缓存)instruments
,但性能仍然很糟糕。我相信这是因为即使视图正在被缓存,如果它不是不透明的,那么它仍然必须在每一帧中重新渲染。
需要强调的一件事是,如果只有几个视图被屏蔽(甚至十个左右),则性能非常好。但是,当您将其增加到 时100 or more
,性能会滞后。我想这是因为当一个人越过其他人时,他们都必须重新渲染。
我的结论是,我有两种选择之一。
首先,必须有某种方式永久屏蔽视图(渲染一次并称其为良好)。我知道这可以通过我在示例代码中显示的图形或位图上下文路由来完成,但是当图层掩盖其视图时,它会立即发生。当我在如图所示的位图上下文中执行此操作时,它非常慢(因为它几乎无法比较它有多慢)。
其次,必须有某种faster
方法可以通过位图上下文路由来实现。如果有屏蔽图像或视图的专家,将非常感谢他们的帮助。