viewDidLoad 中的边界和帧大小
Posted
技术标签:
【中文标题】viewDidLoad 中的边界和帧大小【英文标题】:Bounds and Frame size in viewDidLoad 【发布时间】:2012-10-01 20:14:22 【问题描述】:我推送一个视图控制器 (mainVC
) 并向其中添加一些子视图。大多数这些视图都是按需构建的,因为用户会采取一些行动。
当我构建每个视图时,我参考mainVC.view.bounds
来调整视图的大小。根据需求大小构建的那些很好,但第一个(我在viewDidLoad
添加)似乎没有考虑隐藏的导航栏或未隐藏的工具栏 - 我不确定是哪个。
其他问题似乎向我保证 viewDidLoad 是引用边界和添加这些子视图的正确位置。我被误导了吗?日志记录产生以下结果:
在viewDidLoad
中,边界高度为 548。
在viewWillAppear
中,边界高度为 460 (-44 x 2)。在viewWillAppear
我隐藏了导航栏,但是前后高度是一样的。
在以后的所有时间里,边界高度都是 504 (-44 x 1)。
为什么当我尝试在viewDidLoad
中阅读时边界高度没有更新?
【问题讨论】:
我假设第一次加载笔尖时,视图是您设置的任何大小。当它最终成为窗口中的子视图时,系统会根据其所在位置调整它的大小(我假设)。请注意,没有“硬”大小 - 我启用了网络共享,因此视图比正常视图短 20 像素。 【参考方案1】:视图控制器生命周期在View Controller Programming Guide for ios 中描述。
简而言之,当-view
第一次被调用时,-viewDidLoad
被调用。即使视图控制器对视图所做的第一件事就是设置框架,它仍然需要访问视图。
UIViewController *controller = [MyViewController myViewController];
// -viewDidLoad has not been called (if +myViewController doesn't call -view.)
UIView *view = [controller view];
// -viewDidLoad has been called.
view.frame = [UIApplication sharedApplication].delegate.window.bounds;
即使您使用controller.view.frame
,也会发生相同的逻辑顺序。 -viewDidLoad
将始终使用尚未嵌入视图层次结构的新反序列化视图进行调用。
更新
如果之前不清楚,我指出为什么在-viewDidLoad
中没有正确设置视图边界。只有在-viewDidLoad
之后,视图控制器的视图才会添加到视图层次结构中。这是设置视图的最后一帧的时间。
如果您必须让框架具有正确的尺寸,您可以使用 IB 设置您知道需要的尺寸,或者(如果您不使用 IB)在 -loadView
中设置框架。这种方法是有缺陷的,因为它静态地将帧的大小设置为在调用-viewDidLoad
之后可能会更改的值(例如通话状态栏)。
更新 2
您需要将添加子视图与定位和调整子视图分开。
如果您是从 Storyboard 或 Nib 加载,那么您是对的,需要的额外视图应添加到 -viewDidLoad
。如果您以编程方式加载,则所有子视图都添加到-loadView
。
第二个任务是定位和调整子视图。首选方法是使用UIView.autoresizingMask,但为了更精确的布局,KVO view.bounds 并在视图控制器的视图更改其大小时调整您的自定义子视图。
【讨论】:
即使我在创建控制器后立即请求[控制器视图],也没有什么区别。首先我创建控制器。其次,我(现在)只是将控制器的视图分配给一个变量——只是为了引用它。然后我改变框架。对于任何按需加载的周期,这都有效 - 对于 mainVC 的视图 didLoad 中的任何触发,它都不起作用。如果我误解了,并且您在示例中指的是我的 mainVC,那么我打算如何在启动时加载其他一些视图控制器并添加它们的视图? 抱歉,我可能不清楚-viewDidLoad
将始终在设置最终边界或框架之前被调用。总是。您对此无能为力。
我应该在哪里添加子视图?在视图中会出现吗?好像我会做很多不必要的重新处理。
简短的回答是从定位和调整子视图中拆分添加子视图。
@Jeffery Thomas:我在这里也有类似的问题,我认为您的反馈会很有用:***.com/questions/17882199/…以上是关于viewDidLoad 中的边界和帧大小的主要内容,如果未能解决你的问题,请参考以下文章
在 viewDidLoad 外部调用方法时未显示相机胶卷中的最后一张图像