Search code examples
iphoneiosuiscrollviewcore-animation

Animate scrolling of UIScrollView with CoreAnimation


Sorry for a big question, real question are bold in bottom, now some explanation.

I'm use CoreAnimation in my project for animate some objects moving like this.

CABasicAnimation *moveAnimation;        
moveAnimation=[CABasicAnimation animationWithKeyPath:@"position"];      
moveAnimation.duration = 2.0;       
moveAnimation.repeatCount=1;        
moveAnimation.autoreverses=NO;  
moveAnimation.delegate = self;
moveAnimation.fromValue = [NSValue valueWithCGPoint:[crawler.layer position]];
moveAnimation.fillMode = kCAFillModeForwards;
moveAnimation.removedOnCompletion = NO;
CGPoint p;
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
[crawler.layer addAnimation:moveAnimation forKey:@"moveAnimation"];

And now I need to animate scrolling of some UIScrollView. I can't use setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated method, because it can't customise animation duration.

I can make it like this

CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:2];
[UIView setAnimationDelegate:self];
scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x + 200, scrollView.contentOffset.y);
[UIView commitAnimations];

but it's not CoreAnimation, and using 2 different kinds of animation techniques in one app is not a good practice, I think.

Is there a way to use a CoreAnimation to animate scrolling of UIScrollView content to custom point with custom animation duration? P.S. Sorry for the bad English.


Solution

  • You should read about animatable properties, Programming iOS 5

    Indeed, when you try to animate layers, Apple gives a set of animatable properties, but you're not limited to this set. You can animate whatever you want.

    In all cases, you shouldn't use kCAFillModeForwards because it will ask the device to redraw forever the last presentation layer that was used for the animation, instead of using a cached representation of the layer.

    So the way you could achieve such a thing would be by defining a specific layer of yours where the contentOffset property is defined as animatable. And in order to work, you should start by verifying what kind of top layer class is used by a scrollview, so that, by subclassing it and setting the wanted property (contentOffset) animatable, and subclassing your scrollview by setting this layer as the top layer of the scrollview, you could possibly achieve what you're trying to do.

    This is theory!

    But this is what I would try. Look for this method and its behavior and intents

    + (BOOL)needsDisplayForKey:(NSString *)key
    

    Another thing you could read is this A start example. But this also means you should redraw your uiscrollview by yourself!