2010-11-29 43 views
2

我有一个UINavigationController,并从根视图控制器推送到下一个视图控制器。这第二个视图控制器相当“沉重”,因为它有很多初始化和子视图。UINavigationController推送转换期间的低帧率

我的问题是:过渡动画表现非常糟糕。基本上,动画遭受非常低的帧速率(我从“推”动画中总共可以获得3-4帧)。

我已经尝试了各种不同的技术,包括两种不同的方法来手动设置过渡动画。在所有情况下,动画的第一个0.4-0.7秒都会受到这种糟糕的帧率的影响。例如,如果我设置过渡时间为5秒,则前半秒左右表现不佳,但动画的其余部分非常平滑。

这使我相信在转换开始时会发生“某些事情” - 这会导致设备以非常低的帧率动画。

在我的代码中注入了很多NSLog声明后,我看到两件事情发生。首先,显然第二种观点在推动期间被延迟加载。我通过在执行推送之前访问视图属性上的getter来解决此问题。我可以确认这会导致在推动动画开始之前发生的所有初始化。

其次,我的应用大多数时间在转换过程中收到低内存警告。然而,即使在我没有得到记忆警告的情况下,动画仍然表现不佳 - 让我相信这些东西都不是原因。

我的问题:是否有其他人经历UINavigationController推过渡动画的低帧率,但只有动画的第一个0.4-0.7秒?在幕后有没有其他的事情发生,并且可以做任何事情?

作为参考,这里是我的当前代码加载并推送到下一个视图。我有意访问视图获取器,以强制视图在转换之前加载和初始化(主要是为了排除此问题)。此代码在主线程上执行,使用performSelectorOnMainThread:::响应Web服务回调。

PlayingFieldViewController *v = [[PlayingFieldViewController alloc] initWithNibName:@"PlayingFieldView" bundle:[NSBundle mainBundle]]; 
UIView *lazy = v.view; 
[appDelegate.navigationController pushViewController:v animated:YES]; 
[v release]; 

我也尝试了一些其他的动画技术,都具有相同的结果:

CATransition *transition = [CATransition animation]; 
transition.duration = 1.0; 
transition.type = kCATransitionPush; 
transition.subtype = kCATransitionFromRight; 
[appDelegate.navigationController.view.layer addAnimation:transition forKey:kCATransition]; 
[appDelegate.navigationController pushViewController:v animated:NO]; 

和:

[UIView 
    transitionWithView:appDelegate.navigationController.view 
    duration:1.0 
    options:UIViewAnimationOptionTransitionCurlUp 
    animations:^{ 
    [appDelegate.navigationController pushViewController:v animated:NO]; 
    } 
    completion:NULL]; 
+0

首先,UI更改应该总是在主线程上。但是,你的`viewWillAppear:`方法是什么样的? – 2010-11-29 18:57:36

+0

代码现在正在主线程上执行,但没有任何区别。我其实并没有viewWillAppear:方法,尽管我现在已经放入了少量的东西。有或没有viewWillAppear:,问题依然存在。 – 2010-11-29 19:22:02

回答

3

进一步测试后,我能诊断问题。涉及的第二个观点包括许多UIImageViews。删除这些视图或隐藏它们可以解决问题。

把我抛弃的原因是,只有动画的第一部分遭受帧速率问题,而动画的其余部分非常平滑(在较长动画的情况下)。这表明,即使存在所有子视图,该设备也能够顺利地进行过渡动画。

我仍然不是iOS合成专家,但我猜测各种图层正在布局和缓存,导致放缓。解决方法是将大多数子视图隐藏到视图中,然后在视图可见时使用另一个动画显示它们。

0

我没有在这个与导航控制器绊倒但是当从另一个线程更新表视图时,我得到了相同的结果,开始时UI的更新非常缓慢,但在短暂延迟后,所有内容都再次显示。正如贾斯汀在评论中指出的,你应该在主线程上做UI工作。一个简单的方法来完成,这是包装您的调用UI在GCD块:

dispatch_sync(dispatch_get_main_queue(), ^{ 
// Do UI stuff here 
}); 

或使用

performSelectorOnMainThread:withObject:waitUntilDone:

相关问题