使用kCAMediaTimingFunctionEaseIn是否有问题?

亚伦

我正在使用CALayerCAReplicatorLayerCABasicAnimation设置条形图的动画。条形图由“段”组成,我将其渲染为带有的小矩形CALayer然后,将它们作为子层添加到CAReplicatorLayer循环中。最后,我为每个小矩形添加一个动画,将该矩形放到图表中的位置。

这是动画的最终状态:

纠正动画的最终状态

这是动画中间的样子:

动画状态

这是实现它的代码:

#define BLOCK_HEIGHT 6.0f
#define BLOCK_WIDTH 8.0f

@interface TCViewController ()

@property (nonatomic, strong) NSMutableArray * blockLayers;         // blocks that fall from the sky
@property (nonatomic, strong) NSMutableArray * replicatorLayers;    // replicator layers that will replicate the blocks into position

@end

@implementation TCViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor lightGrayColor];

    self.blockLayers = [NSMutableArray array];
    self.replicatorLayers = [NSMutableArray array];

    NSArray * dataBlocksData = @[@1,@2,@3,@1,@5,@2,@11,@14,@5,@12,@10,@3,@7,@6,@3,@4,@1];

    __block CGFloat currentXPosition = 0.0f;

    [dataBlocksData enumerateObjectsUsingBlock:^(NSNumber * obj, NSUInteger idx, BOOL *stop) {

        currentXPosition += BLOCK_WIDTH + 2.0f;

        if (obj.integerValue == 0) return;

        // replicator layer for data blocks in a column
        CAReplicatorLayer * replicatorLayer = [[CAReplicatorLayer alloc] init];
        replicatorLayer.frame = CGRectMake(currentXPosition, 0.0f, BLOCK_WIDTH, 200.0f);

        // single data block layer (must be new for each replicator layer. can't reuse existing layer)
        CALayer * blockLayer = [[CALayer alloc] init];
        blockLayer.frame = CGRectMake(0, 200-BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT);
        blockLayer.backgroundColor = [UIColor whiteColor].CGColor;
        [replicatorLayer addSublayer:blockLayer];

        replicatorLayer.instanceCount = obj.integerValue;
        replicatorLayer.instanceDelay = 0.1f;
        replicatorLayer.instanceTransform = CATransform3DMakeTranslation(0, -BLOCK_HEIGHT, 0);    // negative height moves back up the column

        [self.blockLayers addObject:blockLayer];                
        [self.replicatorLayers addObject:replicatorLayer];      
    }];
}

- (void)viewDidLayoutSubviews {
    // add replicator layers as sublayers
    [self.replicatorLayers enumerateObjectsUsingBlock:^(CAReplicatorLayer * obj, NSUInteger idx, BOOL *stop) {
        [self.view.layer addSublayer:obj];
    }];
}

- (void)viewDidAppear:(BOOL)animated {

    // add animations to each block layer
    [self.blockLayers enumerateObjectsUsingBlock:^(CALayer * obj, NSUInteger idx, BOOL *stop) {
        // position animation
        CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
        animation.fromValue = @(-300);
        animation.toValue = @(0);
        animation.duration = 1.0f;
        animation.fillMode = kCAFillModeBoth;
        animation.removedOnCompletion = NO;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
        [obj addAnimation:animation forKey:@"falling-block-animation"];
    }];
}

最后,这是要抓住的地方。如果指定no timingFunction,则一个LinearEaseIn多个动画不会完全完成。就像块没有完全落入位。看来他们快要完成了,但还差得很远。只需关闭一两帧即可。交换定时功能分配-viewDidAppear:,您将得到以下怪异:

在此处输入图片说明

继续尝试一下。我什至尝试通过控制点(link指定一个功能,该功能与功能完全相同EaseIn

// use control points for an EaseIn timing:
animation.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0.42 :0.00 :1.0 :1.0];

// or simply specify the ease in timing function:
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

出于某种原因EaseOutDefault定时功能可以正常工作,但样式上的简便似乎需要更长的时间才能完成(在视觉上),这也许是因为插值曲线的长度吗?

我已经尝试了许多方法来缩小问题的范围:

  1. Not looping over these structures and using only 1 layer and 1 replicator layer with the same animation. By that I mean, animate just one column. No luck. Looping isn't the issue.
  2. Put the creation, sublayer-adding and animation-adding code all in -viewDidAppear. Didn't seem to make a difference if the animations were added earlier or later in the view's life cycle.
  3. Using properties for my structures. No difference.
  4. Not using properties for my structures. Again, no difference.
  5. Added callbacks for animation completion to remove the animation so as to leave the columns in the correct "final" state. This was not good but worth a try.
  6. The issue is present in both iOS 6 and 7.

I really want to use an EaseIn timing function because its the best looking animation for something falling into place. I also want to use the CAReplicatorLayer because it does exactly what I want to do.

So what's wrong with the EaseIn timing functions as I'm using them? Is this a bug?

GBegen

I agree that this appears to be a bug in the combination of CAReplicatorLayer and the kCAMediaTimingFunctionEaseIn timing function.

As a workaround, I suggest using a keyframe animation with three keyframes. The first two keyframes define your desired animation with the ease-in timing. The last keyframe is defined to be identical to the second keyframe, but gives the animation additional time to sit on the final keyframe, which seems to let the replicator layer animate that last replicated layer into the final state.

因此,我的建议是:

CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];

//  extra keyframe duplicating final state
animation.values = @[@-300.0f, @0.0f, @0.0f];

//  double length of original animation, with last half containing no actual animation
animation.keyTimes = @[@0.0, @0.5, @1.0];
animation.duration = 2.0f;

animation.fillMode = kCAFillModeBoth;
animation.removedOnCompletion = NO;

//  ease-in for first half of animation; default after
animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
[obj addAnimation:animation forKey:@"falling-block-animation"];

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用queue:cron作业是否有问题?

在 recyclerview 中多次使用“setAdapter()”是否有问题?

使用过多的IF语句是否有问题?迅速

@Provides的顺序是否有问题?

jQuery是否有类问题

此PDF是否有问题?

如果我在JS中使用或不使用“使用严格”模式,是否有问题?

不确定使用volatile是否有意义,似乎有相同的问题

我无法使用Python将坐标导出到shapefile。我的代码是否有问题,或者问题可能出在模块上?

每次不使用都会创建不同的数据库上下文是否有问题

是否有比使用多个for循环更好的方法来解决此问题?

有关隐式UNNEST以及是否对未嵌套的数组字段使用别名的影响的问题

设置可笑的高度(例如10000px)而不是使用高度100%是否有问题?

在同一应用程序中使用TCP和UDP是否有问题?

使用htop命令时,time +列中的红色值是否表示有问题?

使用HTTP上的GET请求发送密码的安全问题是否有效?

使用对象存储从服务器检索到的数据是否有任何问题?

使用C99编译问题是否在每个if周围都有一个范围?

我是否使用eq(...)不正确?还是这里有什么问题?

在Java语言中使用this.variable作为参数默认值是否有问题?

使用Windows os分区与Linux共享数据存储是否有任何问题?

是否有任何性能问题迫使使用火花计数进行急切评估?

使用嵌套哈希表解决此实践问题是否有效?

有关使用ifstream判断C ++中是否存在文件的问题

并行使用头盔2和头盔3是否有任何问题?

跨SATA和eSATA混合使用软件RAID磁盘是否会有任何问题?

临时为两个分区使用相同的UUID是否有问题?

在泛型类中使用非泛型方法是否有任何问题?

@SessionScoped bean是否有并发问题?