• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - CALayer 中的平滑动画孔?

[复制链接]
菜鸟教程小白 发表于 2022-12-13 17:24:19 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

好的,我根据 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);

(holePathUIBezierPath 的一个实例。)

到目前为止一切顺利。下一步是动画。为了做到这一点(我也在 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-推荐答案


好的,我尝试了 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/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap