好的,我根据 SO 上的各种帖子想出了如何做到这一点,而且效果很好。我正在研究一个覆盖层,它基本上会掩盖整个窗口,除了一个小区域。这是为了引起对我应用程序特定区域的关注。我正在使用一堆这样的调用moveToPoint:
(addLineToPoint:
这是在我的 CALayer 子类中drawInContext:
):
....
// inner path (CW)
[holePath moveToPoint:CGPointMake(x, y)];
[holePath addLineToPoint:CGPointMake(x + w, y)];
[holePath addLineToPoint:CGPointMake(x + w, y + h)];
[holePath addLineToPoint:CGPointMake(x, y+h)];
// outer path (CCW)
[holePath moveToPoint:CGPointMake(xBounds, yBounds)];
[holePath addLineToPoint:CGPointMake(xBounds, yBounds + hBounds)];
[holePath addLineToPoint:CGPointMake(xBounds + wBounds, yBounds + hBounds)];
[holePath addLineToPoint:CGPointMake(xBounds + wBounds, yBounds)];
// put the path in the context
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, 0, 0);
CGContextAddPath(ctx, holePath.CGPath);
CGContextClosePath(ctx);
// set the color
CGContextSetFillColorWithColor(ctx, self.overlayColor.CGColor);
// draw the overlay
CGContextDrawPath(ctx, kCGPathFillStroke);
(holePath
是 的一个实例UIBezierPath
。)
到目前为止,一切都很好。下一步是动画。为了做到这一点(我也在SO上找到了这种技术)我做了一个方法如下
-(CABasicAnimation *)makeAnimationForKey:(NSString *)key {
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:key];
anim.fromValue = [[self presentationLayer] valueForKey:key];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
anim.duration = 0.5;
return anim;
}
并覆盖actionForKey:
,initWithLayer:
和needsDisplayForKey:
(返回makeAnimationForKey:
in的结果actionForKey:
。现在,我得到了一个不错的“洞层”,它具有holeRect
可使用隐式 CAAnimations 进行动画处理的属性!不幸的是,它非常不稳定。我每秒得到 2 或 3 帧。我以为可能是背景的问题,并尝试将其替换为快照,但没有骰子。然后,我使用 Instruments 进行分析,发现这里的 HUGE hog 是对CGContextDrawPath()
.
tl;博士我想我的问题归结为:有没有一种更简单的方法来创建这个带有一个洞的图层,这样可以更快地重绘?我的直觉是,如果我可以简化我正在使用的路径,那么绘制路径会更轻松。或者可能掩盖?请帮忙!