問題:
iOS系統(tǒng)由10.x.x版本升級11.0.3后,無意間跑一些老代碼時發(fā)現(xiàn)有些界面的適配出現(xiàn)了錯位。
再三勘察錯誤后發(fā)現(xiàn)本來導航欄設置為不透明,如今卻變成了透明(磨砂)模式,要知道導航欄透明與不透明的區(qū)別除了視覺差異外還有對屏幕左上角坐標點(0,0)的基準是不一樣的。
當導航欄設置為透明模式時--->基準點為手機屏幕最左上角,也就是說如果你在(0,0)點放一個有色label時,你就會發(fā)現(xiàn)導航欄是擋住了你的方塊的,因為是半透明,你能隱約間看到有色塊。
當導航欄設置為不透明模式時--->基準點為導航欄的左下角,也就是說如果你在(0,0)點放一個有色label時,你就會發(fā)現(xiàn)這個色塊緊貼著導航欄左下方,并沒有一絲被遮擋。
所以,界面的適配的錯位其實是由于基準的變化,導致了控件整體上移了64.
眾所周知,更改導航欄透明度設置的代碼為:
self.navigationController.navigationBar.translucent = NO;
經檢查我代碼里確實是有這個設置,而且這個的老代碼之前是經過測試上線的代碼,能通過測試,說明在當時那個版本肯定是沒有問題的,那么問題出在了哪里?
經過一番嘗試,筆者發(fā)現(xiàn)該設置本身是有效的,只不過是放錯了地方。
我原來的代碼結構是將導航欄的相關設置統(tǒng)一抽出一個方法(setNavigationController),然后在方法中處理導航欄相關事宜,這個方法是在viewDidLoad中調用,如下面所示:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self setNavigationController];
..........
}
- (void) setNavigationController {
self.navigationController.navigationBar.translucent = NO;
...........
}
當我嘗試把透明度設置代碼從控制器生命周期viewDidLoad中改到viewWillAppear中時,發(fā)現(xiàn)導航欄設置生效了,從而界面適配又恢復了正常的樣子。故:
解決方法
將self.navigationController.navigationBar.translucent = NO;放在控制器生命周期的viewWillAppear中處理即可
解決原因猜想
這個問題是發(fā)現(xiàn)在11.0.3版本上的,之前較低的版本并沒有這個問題,所以應該是蘋果在新版本中更改了控制器生命周期中一些方法的具體工作內容,因為導航欄是在Appdelegate中生成的,所以在控制器中本身是已經存在的,對于一個已經存在的對象修改其外表屬性發(fā)現(xiàn)沒有效果,結果可能就是這個對象還沒有進入渲染和展示,進一步推斷,蘋果在新版本中將viewDidLoad里部分負責渲染和展示的工作移動到了下一個生命周期。即:viewWillAppear。
以上為個人無責任猜想,如果理解有謬誤,懇請斧正。
最后,一句話長求總
如果你需要設置導航欄透明度,切記把
self.navigationController.navigationBar.translucent = NO;
寫到ViewWillAppear里!