创建肯 - 伯恩斯效应的问题

时间:2011-09-08 07:46:29

标签: iphone objective-c animation

我目前正在尝试在UIImageView上创建Ken Burns effect。它首先应该放大(缓慢),然后动画的didStopSelector应该调用一个方法,该方法应该缩小。问题是,只要我没有将didStopSelector添加到动画中,第一个动画(放大)就可以正常工作。如果我这样做,似乎直接调用该方法(而不是在它之后调用)。

以下是包含动画的2种方法:

- (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 = CGAffineTransformScale(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];
}

在初始化UIImageView之后,我将当前的Transform和Center值保存到属性中。

self.origTransform = self.view_image.transform;
self.origPoint = self.view_image.center;

我也只用了一个动画和setAnimationAutoReverse来尝试它,但在动画完成后,它会放大而不用动画(在它缩小后慢慢动画)。

也许你知道问题可能是什么。

提前谢谢你:)

3 个答案:

答案 0 :(得分:0)

如果从主线程调用endKenBurnsEffect会发生什么?

即。将[UIView setAnimationDidStopSelector:@selector(endKenBurnsEffect)];更改为`[UIView setAnimationDidStopSelector:@selector(invokeEndKenBurnsEffect)];'

-(void)invokeEndKenBurnsEffect的样子:

-(void)invokeEndKenBurnsEffect
{
    [ self performSelectorOnMainThread:@selector( endKenBurnsEffect )
                            withObject:nil 
                         waitUntilDone:NO ] ;
}

答案 1 :(得分:0)

您是否尝试过使用CAAnimationGroup并使用一些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 ] ;

......这只是草稿

答案 2 :(得分:0)

您仍然可以使用带递归的基于块的动画:

在你的.h文件中

@interface YourClass : UIViewController{
    BOOL kenBurnsIsAnimating;
}

在你的.m文件中

- (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];
                             }
                         }];
    }    
}

这样你就可以用递归创建转换,你将在动画块中做的任何事情都会一次又一次地发生(这就是为什么有isOpening YES / NO值),直到你不会将kenBurnsIsAnimating设置为NO。但是,目前的动画仍然需要完成。

有关基于块的动画检出的更多信息http://developer.apple.com/library/IOS/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html#//apple_ref/doc/uid/TP40009503-CH6-SW4还有一个示例可以将两个基于块的动画相互连接。清单4-2。