设置layer.transform会在结束位置闪烁图层,然后从当前位置对其进行动画处理

时间:2010-06-17 15:39:13

标签: iphone core-animation transform blink

有时将layer.transform设置为新变换时,我会看到图层在其完成位置闪烁,然后从当前位置动画到其完成位置。

我不知道这是否相关,但同时我在图层的超级图层上设置了sublayerTransform。

我真的不知道为什么会这样,任何想法都会受到赞赏。

感谢。

更新

当我删除子图层转换时,不会发生此行为。

这是我的初步设置。

我避免使用sublayerTransform的隐式操作:

self.actions = [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"sublayerTransform"];

此方法转换单个图层

- (void)setSelectedCover:(int)cover{    
    selectedCover = cover;

    CoverLayer *coverLayer = [onScreenCovers objectForKey:[NSNumber numberWithInt:cover]];

    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithFloat:0.3f]
                    forKey:kCATransactionAnimationDuration];

    coverLayer.transform = flippedUpTransform;
    [CATransaction commit];
}

此方法创建类似滚动的效果(我知道有更方便的滚动方式,但到目前为止这是我需要的最佳实现)只要手指在屏幕上移动,就会调用此方法。

- (void)setScrollOffset:(float)offset absolute:(BOOL)absolute animated:(BOOL)animated{
     CATransform3D aSublayerTransform = self.sublayerTransform;
     scrollOffset = aSublayerTransform.m41;

     if (absolute) {
        scrollOffset = offset;
     }else {
        scrollOffset += offset;
     }

     [self setValue:[NSNumber numberWithInt:scrollOffset] forKeyPath:@"sublayerTransform.translation.x"];
}

另外。我只能在第二代设备(不是第3代)上重现这一点,所以它让我觉得它部分是设备性能问题,但我仍然需要解决这个问题。

我考虑过像这样使用CABasicAnimation(显式动画):

  - (void)setSelectedCover:(int)cover{  
    selectedCover = cover;

    CoverLayer *coverLayer = [onScreenCovers objectForKey:[NSNumber numberWithInt:cover]];

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.toValue = [NSValue valueWithCATransform3D:flippedUpTransform];
    animation.duration = 0.3f;

        [coverLayer addAnimation:animation forKey:@"transform"];
   }

这实际上工作得很好,没有闪烁!现在唯一的问题是让它留下来。

所以我把它添加到动画中:

animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;

这实际上让它停留在动画的最后但是我认为对于正在从事类似任务的人来说,知道添加这两行只会使表示层坚持下去并且它不会持续存在很重要它出现在模型层中。在我的情况下,如果我想再次变换,我有另外的变换,通过说layer.transform = newtransform并且模型永远不会改变,我的图层将恢复为在我执行显式动画之前它的原始变换。

所以我认为我对持久化转换的问题有了很好的解决方法。我补充说:

animation.delegate = coverLayer.delegate;

在我的情况下,每个获得动画的图层都需要自己的委托,因为我可以同时动画多个图层,因为事情移动得太快了。所以我希望每一层都对自己负责。

这是我在委托中实现的内容。

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{

   if (flag) {

    [CATransaction begin];
    [CATransaction setValue:(id)kCFBooleanTrue
                     forKey:kCATransactionDisableActions];
    cover.transform = flippedUpTransform;
    [CATransaction commit];
    [cover performSelector:@selector(removeAllAnimations) withObject:nil afterDelay:0.2];

   }
}

如果动画成功完成,我将完成转换并将其应用于模型本身

我删除显式动画后不久,因为当设置了其他变换时,它将运行我上次添加的动画。

这很有效。

如果动画没有完成,我什么都不做。我不需要更新模态层,因为中断的动画应该负责拾取这个停止的位置并确保演示文稿保持不变。

问题在于延迟通话始终是正确的。它们不是,它将它保持在一起,但有时事情看起来有点不合适。最后我会接受这个解决方案如果我不能进一步纠正它。它不是那么顺利......

2 个答案:

答案 0 :(得分:0)

如果你要显示你正在使用的代码会有所帮助,但有时我看到当代码动画属性(在你的情况下转换)然后在稍后的运行循环中设置属性时会出现闪烁。发生的事情是它将动画添加到它(图层)两次。请记住,直接更改非根层属性将(隐式)为该属性设置动画,除非您禁用动画。此外,请记住动画属性不会自动设置属性。如果您使用显式动画,请确保在向图层添加动画时,使用“transform”作为键 - 例如:

CABasicAnimation *transformAnim = [CABasicAnimation 
                                         animationForKey:@"transform"];
[transformAnim setToValue:CATransform3DMake...];
[transformAnim setDuration:...]; // etc. etc.

// This next line actually sets the transform
[transformLayer setTransform:CATransform3DMake...];
// This overrides the default animation for animating the transform
[transformLayer addAnimation:transformAnim forKey:@"transform"];

不确定您是否使用了明确的动画,但这就是我想到的。

另外,你是sublayerTransform可能会影响这个。当你评论出来时会发生什么?如果您使用某些代码更新问题,可能会有所帮助。

最好的问候。

答案 1 :(得分:0)

iOS4更新解决了这个问题。