好的,我根据 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 *)makeAnimationForKeyNSString *)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: 的结果在actionForKey: 。现在,我得到了一个不错的“洞层”,它有一个属性 holeRect 可以使用隐式 CAAnimations 进行动画处理!不幸的是,它非常不稳定。我得到了类似 2或每秒3帧。我认为可能是背景的问题,并尝试将其替换为快照,但没有骰子。然后,我使用 Instruments 进行分析,发现这里的 HUGE hog 是对 的调用CGContextDrawPath() .
tl;dr 我想我的问题归结为:有没有更简单的方法来创建这个层,其中有一个孔,可以更快地重绘?我的直觉是,如果我可以简化我正在使用的路径,那么绘制路径会更轻松。或者可能掩盖?请帮忙!
Best Answer-推荐答案 strong>
好的,我尝试了 phix23 的建议,它完全成功了!起初,我将 CALayer 子类化并添加一个 CAShapeLayer 作为子层,但我无法让它正常工作,此时我已经很累了,所以我放弃了,只是用 CAShapeLayer 完全替换了我的子类!我在自己的方法中使用了上面的代码,返回 UIBezierPath ,并像这样动画:
UIBezierPath* oldPath = [self pathForHoleRect:self.holeRect];
UIBezierPath* newPath = [self pathForHoleRect:rectToHighlight];
self.holeRect = rectToHighlight;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath"path"];
animation.duration = 0.5;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.fromValue = (id)oldPath.CGPath;
animation.toValue = (id)newPath.CGPath;
[self.holeLayer addAnimation:animation forKey"animatePath"];
self.holeLayer.path = newPath.CGPath;
有趣的附注——path 不是隐式可动画的。我想这是有道理的。
关于ios - CALayer 中的平滑动画孔?,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/13080440/
|