CALayer上的变换属性的CAKeyFrameAnimation未按预期工作

我一直在这里工作了一段时间,彻底搜索了解决方案,但无济于事。 这是我想要做的。

我有一个UIScrollView用户可以放大和平移5秒。 我有一个单独的CALayer,它不在UIScrollView的顶层。 我想缩放和翻译此CALayer的内容以反映在UIScrollView上发生的缩放和平移。 我想通过关键帧动画CAKeyFrameAnimation实现这CAKeyFrameAnimation 。 当我把它放到代码中时,缩放按预期发生,但内容的位置被错误地偏移。

这是我如何在代码中完成的。 假设UIScrollView委托将缩放比例和内容偏移量传递给以下方法:

// Remember all zoom params for late recreation via a CAKeyFrameAnimation
- (void) didZoomOrScroll:(float)zoomScale
           contentOffset:(CGPoint)scrollViewContentOffset {

    CATransform3D scale = CATransform3DMakeScale(zoomScale, zoomScale, 1);
    CATransform3D translate = CATransform3DMakeTranslation(-scrollViewContentOffset.x, 
                                                           -scrollViewContentOffset.y, 0);
    CATransform3D concat = CATransform3DConcat(scale, translate);

    // _zoomScrollTransforms and _zoomScrollTimes below are of type NSMutableArray
    [_zoomScrollTransforms addObject:[NSValue valueWithCATransform3D:concat]];

    // secondsElapsed below keeps track of time
    [_zoomScrollTimes addObject:[NSNumber numberWithFloat:secondsElapsed]];
}

// Construct layer animation
- (void) constructLayerWithAnimation:(CALayer *)layer {

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    animation.duration = 5.0;
    animation.values = _zoomScrollTransforms;

    // Adjust key frame times to contain fractional durations
    NSMutableArray *keyTimes = [[NSMutableArray alloc] init];
    for( int i = 0; i < [_zoomScrollTimes count]; i++ ) {
          NSNumber *number = (NSNumber *)[_zoomScrollTimes objectAtIndex:i];
          NSNumber *fractionalDuration = [NSNumber numberWithFloat:[number          floatValue]/animation.duration];
         [keyTimes addObject:fractionalDuration];
    }
    animation.keyTimes = keyTimes;

    animation.removedOnCompletion = YES;
    animation.beginTime = 0;
    animation.calculationMode = kCAAnimationDiscrete;
    animation.fillMode = kCAFillModeForwards;
    [layer addAnimation:animation forKey:nil];
}

当上面的图层动画时,内容会正确放大,但定位不正确。 内容似乎是xy偏移量超出了我的预期,因此不会完全回溯用户在UIScrollView上完成的缩放/平移。

任何想法我可能做错了什么?

回答

好的,我知道我做错了什么。 它必须与CALayer的锚点有关。 CALayers上的转换始终应用于定位点。 对于CALayers,默认情况下,定位点为(0.5,0.5)。 因此正在沿着中心点进行缩放和翻译。 另一方面,UIScrollViews从视图的左上角给出偏移量。 基本上,您可以考虑UIScrollView的锚点,以便考虑CGPoint偏移值,为(0.0,0.0)。

所以解决方法是将CALayer的锚点设置为(0.0,0.0)。 然后一切按预期工作。

还有其他资源以更好的方式呈现此信息。 在Stackoverflow上看到类似的其他问题。 另请参阅苹果文档中的文章,详细讨论几何中的位置,定位点和一般图层。


您将翻译矩阵与缩放矩阵连接起来。 位移偏移的最终值将为偏移量(X,Y)=(scaleX * Tx,scaleY * Ty)。

如果你想用(Tx,Ty)偏移来移动UIView,那么连接平移和缩放矩阵如下:

CATransform3D scale = CATransform3DMakeScale(zoomScale, zoomScale, 1);
CATransform3D translate = CATransform3DMakeTranslation(-scrollViewContentOffset.x, 
                                                       -scrollViewContentOffset.y, 0);
CATransform3D concat = CATransform3DConcat(translate, scale);

试试这个,让我知道它是否有效。

链接地址: http://www.djcxy.com/p/74171.html

上一篇: CAKeyFrameAnimation of transform property on CALayer not working as expected

下一篇: Unpredictable behavior with Core Animation (CABasicAnimation)