我目前正在尝试在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来尝试它,但在动画完成后,它会放大而不用动画(在它缩小后慢慢动画)。
也许你知道问题可能是什么。
提前谢谢你:)
答案 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。