很多时候我比较喜欢用代码添加视图,特别是要同时添加很多UIView时,而且跟xib比起来更容易管理,在多人的项目中代码不容易conflict.
UIViewController 中动态添加UIView正确的步骤应该是:
1.在viewDidload 中创建要添加的UIView..为什么不能在viewWillAppear中创建?根据苹果的文档,这里是添加last minute 修改的地方,比如修改视图的位置,颜色等等,如果在这里创建很多视图,会导致显示延迟.
2.创建的时候最好为每个UIView 加上约束,(NSLayoutConstraint) ,这样在不同大小的屏幕中都可以正确显示.
3.不用约束也行,必须在viewDidLayoutSubviews中修改视图的frame
下面我们来复习一下UIViewController的生命周期;
A.init...
B.loadView
C.viewDidLoad
D.viewWillAppear
E.viewWillLayoutSubviews
F.viewDidLayoutSubviews
G.viewDidAppear
H.viewWillDisappear
I.viewDidDisappear
J.viewDidUnload (not used any more)
K.dealloc...
现在咱可以做个实验: 在项目中选一个View Contorller ,它的 xib 中的视图大小为 600×600, 在其 .m 文件中以上的 C, D,E,F,G方法打印出视图的frame,像这样:
-(void)viewDidLoad{
[superviewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(@"%s self.view.frame: %@",__PRETTY_FUNCTION__,NSStringFromCGRect(self.view.frame));
}
-(void)viewWillAppear:(BOOL)animated
{
[superviewWillAppear:animated];
NSLog(@"%s self.view.frame: %@",__PRETTY_FUNCTION__,NSStringFromCGRect(self.view.frame));
}
-(void)viewWillLayoutSubviews
{
NSLog(@"%s self.view.frame: %@",__PRETTY_FUNCTION__,NSStringFromCGRect(self.view.frame));
}
-(void)viewDidLayoutSubviews
{
NSLog(@"%s self.view.frame: %@",__PRETTY_FUNCTION__,NSStringFromCGRect(self.view.frame));
}
-(void)viewDidAppear:(BOOL)animated
{
[superviewDidAppear:animated];
NSLog(@"%s self.view.frame: %@",__PRETTY_FUNCTION__,NSStringFromCGRect(self.view.frame));
}
选择设备为 iPhone 5, 运行程序后会得到类似这样的结果:
[TaskDetailsViewControllerviewDidLoad]self.view.frame:{{0,0},{600,600}}
[TaskDetailsViewControllerviewWillAppear:]self.view.frame:{{0,0},{600,600}}
[TaskDetailsViewControllerviewWillLayoutSubviews]self.view.frame:{{0,0},{320,568}}
[TaskDetailsViewControllerviewDidLayoutSubviews]self.view.frame:{{0,0},{320,568}}
[TaskDetailsViewControllerviewDidAppear:]self.view.frame:{{0,0},{320,568}}
大家可以看到,一个视图的大小是在调用 viewWillLayoutSubviews 时才会根据设备而改变,不过在 IOS 8 中,要到viewDidLayoutSubviews 才正确。根视图的大小改变了,子视图必须相应做出调整才可以正确显示,这就是为什么要在 viewDidLayoutSubviews 中调整动态视图的frame。
By the way,在 IOS 9 中,根视图控件(Root View Controller)的视图大小在 viewDidLoad 中就已经正确了,苹果好像会不时改变这些特点,比如会把系统键盘的视图优先级提高等等。所以小牛哥觉得动态添加视图最安全的方法是,创建视图后马上加上约束,不管日后苹果怎么改都可以正确显示。
网友评论