2010-11-29 58 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: