Can I animate the UIScrollView contentOffset property via its layer?

吃可爱长大的小学妹 提交于 2019-12-03 02:01:45

问题


I want to zoom and scroll a UIScrollView with a CGPathRef. Because of that I assume I have to animate the UIScrollView's layer property? But which property would I animate that would make it equivalent to doing a UIView animation and setting its contentOffset property and zoomScale ?

These are not properties of a CALayer.

Any ideas as to how I would approach this? Again, just want to move the scrollview to a certain contentOffset and zoomScale, but not necessarily linearly from point A to point B, zoom A to zoom B, respectively.

I was thinking a CAKeyFrameAnimation with a CGPathRef, but I don't know which properties to animate.


回答1:


You have to animate the bounds property. In fact, that's what the contentOffset property uses behind the scenes.

Example:

CGRect bounds = scrollView.bounds;

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"];
animation.duration = 1.0;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

animation.fromValue = [NSValue valueWithCGRect:bounds];

bounds.origin.x += 200;

animation.toValue = [NSValue valueWithCGRect:bounds];

[scrollView.layer addAnimation:animation forKey:@"bounds"];

scrollView.bounds = bounds;

If you're curious, the way I used to get this information is the following:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];

[scrollView setContentOffset:CGPointMake(200, 0) animated:NO];

[UIView commitAnimations];

NSLog(@"%@",scrollView);

The NSLog call will output:

<UIScrollView: 0x860ba20; frame = (-65.5 0; 451 367); clipsToBounds = YES; autoresize = W+RM+TM+H; animations = { bounds=<CABasicAnimation: 0xec1e7c0>; }; layer = <CALayer: 0x860bbc0>; contentOffset: {246, 0}>

The animations snippet will list all the active animations, in this case { bounds=<CABasicAnimation: 0xec1e7c0>; }.

Hope this helps.




回答2:


Moving a CALayer around is done by (preferably) setting it's .position property - or possibly the anchorPoint (c.f. the docs on that: http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html ).

...but I don't think you want to mess with the CALayer if you're working with a UIScrollView. Have you tried applying plain CoreAnimations to your ScrollView?

(the problem is: the UIScrollView is implemented on top of CALayer - so even if you can hack it to work today, it's quite likely to break in future iOS versions. If possible, you want to avoid the CALayer for that particular class)




回答3:


Swift 4.2

This example is base on pt2ph8's obj-c answer.

https://stackoverflow.com/a/8741283/6113158

var scrollView = UIScrollView()

func animateScrollView(duration: Double, to newBounds: CGRect) {
    let animation = CABasicAnimation(keyPath: "bounds")
    animation.duration = duration
    animation.fromValue = scrollView.bounds
    animation.toValue = newBounds

    animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)

    scrollView.layer.add(animation, forKey: nil)

    scrollView.bounds = newBounds
}


来源:https://stackoverflow.com/questions/6535450/can-i-animate-the-uiscrollview-contentoffset-property-via-its-layer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!