Can I animate the UIScrollView contentOffset property via its layer?

后端 未结 3 1063
梦如初夏
梦如初夏 2021-01-30 14:37

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 th

相关标签:
3条回答
  • 2021-01-30 14:44

    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
    }
    
    0 讨论(0)
  • 2021-01-30 14:45

    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)

    0 讨论(0)
  • 2021-01-30 15:05

    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.

    0 讨论(0)
提交回复
热议问题