UIView动画很糟糕地互动

时间:2009-05-08 23:54:51

标签: iphone animation uiview

我看到的是单独的动画之间的相互作用,我真的很感激任何消除这种效果的建议。

基本上: 我有一个iPhone应用程序,在根视图上包含一个按钮'a'。点击“a”会使用翻转动画在导航视图控制器堆栈上推送视图。推送的视图有一个按钮,可以将视图弹回到根目录。

底层代码:

- (IBAction)pushOneView{
TheAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight 
                    forView:delegate.navigationController.view cache:NO];
[delegate.navigationController 
            pushViewController:oneViewController animated:NO];
[UIView commitAnimations];

}

这似乎工作正常,动画非常流畅。

根视图还包括子视图('panelView')和另一个按钮'b'。 panelView可以显示另外两个子视图 - 使用旋转动画点击这些子视图之间的“b”交换。代码:

-(IBAction)swapPanels{
UIViewController *coming;
UIViewController *going;
float rotation;

if (self.aPanel.view.superview == nil) {
    coming = aPanel;
    going = bPanel;
    rotation = 3.14;
}
else {
    coming = bPanel;
    going = aPanel;
    rotation = -3.14;
}

// First half of spin
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
CGAffineTransform swirlTransform = CGAffineTransformMakeRotation(rotation);
panelView.transform = swirlTransform;
[panelView setAlpha:0.1];
[UIView commitAnimations];

// Finish spin
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
CGAffineTransform secondTransform = 
                        CGAffineTransformRotate(swirlTransform, rotation);
panelView.transform = secondTransform;
[panelView setAlpha:1];
[UIView commitAnimations];

// Swap the panels
[going.view removeFromSuperview];
[panelView insertSubview:coming.view atIndex:0];

}

这似乎也很好。每个可交换面板都包含一个拾取器和一些标签。

然而,我注意到,如果'b'转换已经在它之前执行,'a'转换变得缓慢而且不稳定。 换句话说,如果我启动应用程序,来回运行'a'几次,它会顺利运行。然后来回运动'b'几次。然后再试一次'a''a'现在是生涩的,并且会一直这样,直到应用程序重新启动。

这是100%可重复的。它使用模拟器很微妙,但在设备上非常明显。 我已经测试了泄漏 - 没有泄漏工具显示。 如果动画从'b'操作中移除(只是注释掉动画步骤),则在执行'b'子视图交换后,对'a'的影响是而不是。 如果从可交换面板笔尖移除拾取器,则同样消除了该效果。 如果'a'动画过渡被设置为缓存,那么在'b'之后它不会在中间断断续续,但似乎忽略了动画,只是交换视图(这可能是感知问题)。

如果我不清楚:我不会同时触发这些单独的操作。动画'a','b'执行完毕后 - 已完成 - 与'b'从未执行过的动画'a'不同。动画后我应该做清理吗?我的子视图交换代码有缺陷吗?还是...?

提前感谢任何建议。

2 个答案:

答案 0 :(得分:8)

“b”部分中有两个重叠的动画。使用begin / commit块创建动画时,会将其传递给后台线程执行。在你的'b'部分,应该是连续的两个动画实际上几乎同时被发射。这可能会导致奇怪的行为,可能就像你所看到的那样。

我建议使用以下代码将第一个动画中的回调添加到委托方法中:

[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(rotationAnimationFinished:finished:context:)];

在'b'中的第一个动画块中(“旋转的前半部分”部分)。然后,您需要在类中定义回调方法,在本例中为

- (void)rotationAnimationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context;

在该旋转动画的第一部分完成后调用的委托方法中,放置“b”方法中的剩余代码(“完成旋转”注释后的所有内容)。

将这些动画分开,这可能会阻止你所看到的怪异。

答案 1 :(得分:2)

布拉德的答案确实似乎引导我找到解决方案:症状继续表明运行这些'b'动画的某些东西使系统处于与开始时不同的状态。最后,我发现panelView的转换属性是在'b'动画之后设置的......也许这会影响包含panelView的超级视图的动画。

所以我按照Brad的建议设置方法,在'b'动画完成后执行 - 但所有方法都将panelView变换设置为默认值:CGAffineTransformIdentity:

  • (void)spinFinished:(NSString *)animationID finished:(BOOL)完成上下文:(void *)context { panelView.transform = CGAffineTransformIdentity; }

有了这个,'a'动画的后'b'执行似乎恢复正常。再次感谢布拉德,感谢你的帮助。 很多赞赏。