3

我看到似乎是单独动画之间的交互,我非常感谢任何消除这种影响的建议。

基本上:我有一个 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' 从未被执行是不一样的。动画后我应该做清理工作吗?我的子视图交换代码有缺陷吗?或者...?

在此先感谢您的任何建议。

4

2 回答 2

8

您的“b”部分确实有两个重叠的动画。当您使用开始/提交块创建动画时,它会被移交给后台线程来执行。在您的“b”部分中,应该连续的两个动画实际上几乎同时被触发。这可能会导致奇怪的行为,可能就像您所看到的那样。

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

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

在“b”中的第一个动画块中(“旋转的前半部分”部分)。然后你需要在你的类中定义回调方法,在这种情况下

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

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

通过将这些动画分开,这可能会防止您看到的怪异现象。

于 2009-05-09T03:20:01.100 回答
2

Brad 的回答似乎确实让我找到了一个解决方案:这些症状继续表明运行那些“b”动画的某些东西使系统处于与启动时不同的状态。最后,我想到 panelView 的transform属性是在“b”动画之后设置的……也许这会影响包含 panelView 的超级视图的进一步动画。

所以我按照 Brad 的建议设置了方法,在“b”动画完成后执行——但该方法所做的只是将 panelView 转换设置回默认值:CGAffineTransformIdentity:

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

有了这个,“a”动画的“b”后执行似乎恢复了正常。再次感谢布拉德,感谢您在这里的帮助。非常感谢

于 2009-05-09T17:39:51.250 回答