1

有时将 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"];
}

还。我只能在第 2 代设备(不是第 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];

   }
}

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

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

这行得通。

如果动画没有完成,我什么也不做。我不需要更新模态层,因为中断的动画应该负责从中断的地方开始,并确保演示持续存在。

问题在于依赖延迟呼叫始终正确。他们不是,它足够保持在一起,但有时事情看起来有点不对劲。最后我会接受这个解决方案如果我不能进一步纠正它。就是没那么流畅...

4

2 回答 2

0

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

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 可能会影响这一点。当您将其注释掉时会发生什么?如果您使用一些代码更新您的问题,这可能会有所帮助。

最好的祝福。

于 2010-06-18T19:38:08.327 回答
0

iOS4 更新解决了这个问题。

于 2010-06-23T17:36:14.860 回答