Problems with creating a Ken-Burns Effect
I'm currently trying to create a Ken Burns effect on an UIImageView. It firstly should zoom-in (slowly) and after that, the didStopSelector of the Animation should call a method, which should zoom-out. The Problem is, that the first animation (zoom-in) is okay and works perfectly, as long as I don't add the didStopSelector to the animation. If I do so, it seems like the method is called directly (not after it didStop).
Here are the 2 Methods which include the animations:
- (void)beginKenBurnsEffect {
[UIView beginAnimations:@"a" context:self.view_image];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:5];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDidStopSelector:@selector(endKenBurnsEffect)];
[UIView setAnimationDelegate:self];
self.view_image.transform = CG开发者_如何学CAffineTransformScale(self.view_image.transform, 1.06, 1.06);
self.view_image.center = CGPointMake(self.frame.size.width/1.7, self.frame.size.height/2);
[UIView commitAnimations];
}
- (void)endKenBurnsEffect {
[UIView beginAnimations:@"b" context:self.view_image];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:5];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDidStopSelector:@selector(beginKenBurnsEffect)];
[UIView setAnimationDelegate:self];
self.view_image.transform = self.origTransform;
self.view_image.center = self.origPoint;
[UIView commitAnimations];
}
After I initialized the UIImageView, I save the current Transform and Center values to a property.
self.origTransform = self.view_image.transform;
self.origPoint = self.view_image.center;
I also tried it with only one animation and setAnimationAutoReverse, but after the animation is done, it zooms-in without animation (after it did zoom-out slowly animated).
Maybe you have an idea what the problem could be.
Thank you in advance :)
Have you tried using a CAAnimationGroup and using a few CAAnimations?
NSMutableArray * animations = [ NSMutableArray array ] ;
{
CAAnimation * anim = [ CABasicAnimation animationWithKeyPath:@"transform" ] ;
anim.fromValue = [ NSValue valueWithCGAffineTransform:CGAffineTransformScale(...) ] ;
[ array addObject:anim ] ;
}
{
CAAnimation * anim = // make intro position transform
[ array addObject:anim ] ;
}
{
CAAnimation * anim = // make outro position transform for layer.transform
anim.offset = 5.0;
}
{
CAAnimation * anim = // make outro position transform for layer.position
anim.offset = 5.0;
}
CAAnimationGroup * group = [ CAAnimationGroup animation ] ;
group.animations = animations ;
[ CATransaction begin ] ;
[ self.view.layer addAnimation:group forKey:nil ] ;
[ CATransaction commit ] ;
... this is just a rough draft
What happens if you call endKenBurnsEffect from your main thread?
i.e. change [UIView setAnimationDidStopSelector:@selector(endKenBurnsEffect)];
to `[UIView setAnimationDidStopSelector:@selector(invokeEndKenBurnsEffect)];'
where -(void)invokeEndKenBurnsEffect
looks like:
-(void)invokeEndKenBurnsEffect
{
[ self performSelectorOnMainThread:@selector( endKenBurnsEffect )
withObject:nil
waitUntilDone:NO ] ;
}
You can still use block-based animation with recursion:
In your .h file
@interface YourClass : UIViewController{
BOOL kenBurnsIsAnimating;
}
In your .m file
- (void)viewDidLoad{
kenBurnsIsAnimating = YES;
[self kenBurns:YES];
}
- (void)kenBurns:(BOOL)isOpening{
if (kenBurnsIsAnimating) {
[UIView animateWithDuration:5.0
delay:1.0
options:UIViewAnimationCurveEaseInOut
animations:^{
if (isOpening) {
// do your opening animation (zoom in and panning)
}else{
// do your closing animation (zoom out and panning)
}
}
completion:^(BOOL finished){
if (finished) {
[self kenBurns:!isOpening];
}
}];
}
}
This way you will create transition with recursion and anything what you will do in animation block will be happening over and over again (thats why there is isOpening YES/NO value) until you wont set up kenBurnsIsAnimating as NO. But still, the current animation will have to finish.
For more information about block-based animation check out http://developer.apple.com/library/IOS/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html#//apple_ref/doc/uid/TP40009503-CH6-SW4 There is also example for connecting two block based animation after each other. Listing 4-2.
精彩评论