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