问题:
iOS系统由10.x.x版本升级11.0.3后,无意间跑一些老代码时发现有些界面的适配出现了错位。
再三勘察错误后发现本来导航栏设置为不透明,如今却变成了透明(磨砂)模式,要知道导航栏透明与不透明的区别除了视觉差异外还有对屏幕左上角坐标点(0,0)的基准是不一样的。
当导航栏设置为透明模式时--->基准点为手机屏幕最左上角,也就是说如果你在(0,0)点放一个有色label时,你就会发现导航栏是挡住了你的方块的,因为是半透明,你能隐约间看到有色块。
当导航栏设置为不透明模式时--->基准点为导航栏的左下角,也就是说如果你在(0,0)点放一个有色label时,你就会发现这个色块紧贴着导航栏左下方,并没有一丝被遮挡。
所以,界面的适配的错位其实是由于基准的变化,导致了控件整体上移了64.
众所周知,更改导航栏透明度设置的代码为:
self.navigationController.navigationBar.translucent = NO;
经检查我代码里确实是有这个设置,而且这个的老代码之前是经过测试上线的代码,能通过测试,说明在当时那个版本肯定是没有问题的,那么问题出在了哪里?
经过一番尝试,笔者发现该设置本身是有效的,只不过是放错了地方。
我原来的代码结构是将导航栏的相关设置统一抽出一个方法(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中时,发现导航栏设置生效了,从而界面适配又恢复了正常的样子。故:
解决方法
将self.navigationController.navigationBar.translucent = NO;放在控制器生命周期的viewWillAppear中处理即可
解决原因猜想
这个问题是发现在11.0.3版本上的,之前较低的版本并没有这个问题,所以应该是苹果在新版本中更改了控制器生命周期中一些方法的具体工作内容,因为导航栏是在Appdelegate中生成的,所以在控制器中本身是已经存在的,对于一个已经存在的对象修改其外表属性发现没有效果,结果可能就是这个对象还没有进入渲染和展示,进一步推断,苹果在新版本中将viewDidLoad里部分负责渲染和展示的工作移动到了下一个生命周期。即:viewWillAppear。
以上为个人无责任猜想,如果理解有谬误,恳请斧正。
最后,一句话长求总
如果你需要设置导航栏透明度,切记把
self.navigationController.navigationBar.translucent = NO;
写到ViewWillAppear里!
网友评论