ios – CALayer的动画效果与UIView动画相同

ios – CALayer的动画效果与UIView动画相同,第1张

概述我有一个有16个子图层的类来形成徽标.当我为UIView设置动画时,CALayers不会被动画化,而是像下面的动画gif一样进入最终状态: 我的代码是: @implementation LogoView#define CGRECTMAKE(a, b, w, h) {.origin={.x=(a),.y=(b)},.size={.width=(w),.height=(h)}}#pragma 我有一个有16个子图层的类来形成徽标.当我为UIVIEw设置动画时,CALayers不会被动画化,而是像下面的动画gif一样进入最终状态:

我的代码是:

@implementation logoVIEw#define CGRECTMAKE(a,b,w,h) {.origin={.x=(a),.y=(b)},.size={.wIDth=(w),.height=(h)}}#pragma mark - Create SubvIEwsconst static CGRect path[] = {        CGRECTMAKE(62.734375,-21.675000,18.900000,18.900000),CGRECTMAKE(29.784375,-31.725000,27.400000,27.300000),CGRECTMAKE(2.534375,-81.775000,CGRECTMAKE(4.384375,-57.225000,CGRECTMAKE(2.784375,62.875000,CGRECTMAKE(4.334375,29.925000,CGRECTMAKE(62.734375,2.525000,4.475000,CGRECTMAKE(-21.665625,CGRECTMAKE(-31.765625,CGRECTMAKE(-81.615625,-21.425000,CGRECTMAKE(-57.215625,-31.775000,2.775000,4.425000,CGRECTMAKE(-21.415625,27.300000)    };- (voID) createSubvIEws{    self.contentMode = UIVIEwContentModeRedraw;    for (int i = 0; i < 16; i++) {        CGRect rect = CGRectApplyAffinetransform(path[i],CGAffinetransformMakeScale(self.frame.size.wIDth / 213.0,self.frame.size.height / 213.0));        UIBezIErPath * b = [UIBezIErPath bezIErPathWithovalInRect:          CGRectOffset(rect,self.frame.size.wIDth/2.0,self.frame.size.height/2)];        CAShapeLayer * layer = [[CAShapeLayer alloc] init];        layer.path = [b CGPath];        layer.fillcolor = [self.tintcolor CGcolor];        [self.layer addSublayer:layer];    }    self.layer.needsdisplayOnBoundsChange = YES;    self.initialLenght = self.frame.size.wIDth;}- (voID) layoutSublayersOfLayer:(CALayer *)layer{    for (int i = 0; i < 16; i++) {        CGRect rect = CGRectApplyAffinetransform(path[i],CGAffinetransformMakeScale(layer.frame.size.wIDth / 213.0,layer.frame.size.height / 213.0));        UIBezIErPath * b = [UIBezIErPath             bezIErPathWithovalInRect:CGRectOffset(rect,layer.frame.size.wIDth/2.0,layer.frame.size.height/2)];        ((CAShapeLayer*)(layer.sublayers[i])).path = b.CGPath;    }}- (voID)layoutSubvIEws {    [super layoutSubvIEws];    // get current animation for bounds    CAAnimation *anim = [self.layer animationForKey:@"bounds"];    [CATransaction begin];    if(anim) {        // animating,apply same duration and timing function.        [CATransaction setAnimationDuration:anim.duration];        [CATransaction setAnimationTimingFunction:anim.timingFunction];        CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];        [self.layer addAnimation:pathAnimation forKey:@"path"];    }    else {        // not animating,we should disable implicit animations.        [CATransaction disableActions];    }    self.layer.frame = self.frame;    [CATransaction commit];}

我正在制作动画:

[UIVIEw animateWithDuration:3.0 animations:^{        [v setFrame:CGRectMake(0.0,0.0,300.0,300.0)];    }];

如何将图层动画与视图动画同步?

解决方法 与UIVIEw动画同步动画图层属性可能很棘手.相反,让我们使用不同的视图结构来利用内置的支持来动画视图的变换,而不是尝试为图层的路径设置动画.

我们将使用两个视图:supervIEw和subvIEw. supervIEw是一个logoVIEw,是我们在故事板中展示的(或者你创建的UI). logoVIEw为类logoLayerVIEw添加了一个子视图.这个logoLayerVIEw使用CAShapeLayer作为其图层而不是普通的CALayer.

请注意,我们只需要一个CAShapeLayer,因为路径可以包含多个断开连接的区域.

我们将logoLayerVIEw的帧/边界设置为CGRectMake(0,213,213),并且永远不会更改它.相反,当外部logoVIEw更改大小时,我们设置logoLayerVIEw的变换,以便它仍然填充外部logoVIEw.

这是结果:

这是代码:

logoVIEw.h

#import <UIKit/UIKit.h>IB_DESIGNABLE@interface logoVIEw : UIVIEw@end

logoVIEw.m

#import "logoVIEw.h"#define CGRECTMAKE(a,.height=(h)}}const static CGRect ovalRects[] = {    CGRECTMAKE(62.734375,27.300000)};#define logoDimension 213.0@interface logoLayerVIEw : UIVIEw@property (nonatomic,strong,Readonly) CAShapeLayer *layer;@end@implementation logoLayerVIEw@dynamic layer;+ (Class)layerClass {    return [CAShapeLayer class];}- (voID)layoutSubvIEws {    [super layoutSubvIEws];    if (self.layer.path == nil) {        [self initShapeLayer];    }}- (voID)initShapeLayer {    self.layer.backgroundcolor = [UIcolor yellowcolor].CGcolor;    self.layer.strokecolor = nil;    self.layer.fillcolor = [UIcolor greencolor].CGcolor;    UIBezIErPath *path = [UIBezIErPath bezIErPath];    for (size_t i = 0; i < sizeof ovalRects / sizeof *ovalRects; ++i) {        [path appendpath:[UIBezIErPath bezIErPathWithovalInRect:ovalRects[i]]];    }    [path applytransform:CGAffinetransformMakeTranslation(logoDimension / 2,logoDimension / 2)];    self.layer.path = path.CGPath;}@end@implementation logoVIEw {    logoLayerVIEw *layerVIEw;}- (voID)layoutSubvIEws {    [super layoutSubvIEws];    if (layerVIEw == nil) {        layerVIEw = [[logoLayerVIEw alloc] init];        layerVIEw.layer.anchorPoint = CGPointZero;        layerVIEw.frame = CGRectMake(0,logoDimension,logoDimension);        [self addSubvIEw:layerVIEw];    }    [self layoutShapeLayer];}- (voID)layoutShapeLayer {    CGSize mySize = self.bounds.size;    layerVIEw.transform = CGAffinetransformMakeScale(mySize.wIDth / logoDimension,mySize.height / logoDimension);}@end
总结

以上是内存溢出为你收集整理的ios – CALayer的动画效果与UIView动画相同全部内容,希望文章能够帮你解决ios – CALayer的动画效果与UIView动画相同所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1102384.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-28
下一篇2022-05-28

发表评论

登录后才能评论

评论列表(0条)

    保存