有时将 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];
}
}
如果动画成功完成,我将完成转换并将其应用于模型本身
在我删除显式动画后不久,因为设置了其他变换时,它将运行我上次添加的动画。
这行得通。
如果动画没有完成,我什么也不做。我不需要更新模态层,因为中断的动画应该负责从中断的地方开始,并确保演示持续存在。
问题在于依赖延迟呼叫始终正确。他们不是,它足够保持在一起,但有时事情看起来有点不对劲。最后我会接受这个解决方案如果我不能进一步纠正它。就是没那么流畅...