我更喜欢禁用autoresizesSubviews
并使用setFrame
来放置我的所有子视图。从 iOS 6 开始,情况似乎发生了很大变化。当我在视图中调用 setFrame 时viewDidLoad
,没有效果。我试过了viewWillAppear
;一样。
一个 setFrame 调用将在 中工作willAnimateRotationToInterfaceOrientation
,但最初不像在 iOS 5 中那样调用它。
有人可以澄清一下我应该从哪里布局我的观点吗?
我猜你想从 UIViewController 布局你的视图。您是否尝试过在viewDidLayoutSubviews中执行布局任务:
- (void)viewDidLayoutSubviews
根据苹果的文档:
您的视图控制器可以覆盖此方法以在视图布置其子视图后进行更改。
由于您的视图本身不对其子视图进行布局(您不使用 autosize、autolayout 或 layoutSubViews:),您可以在此方法中执行布局任务。
尽管如此,优雅的方法是使用自定义父 UIView 并在那里执行所有布局,覆盖 UIView layoutSubViews:
(除非您动态添加/删除视图)。引用 Apple 关于“视图控制器如何参与视图布局过程”的文档:
理想情况下,视图本身执行所有必要的工作来重新定位自己,而根本不需要视图控制器参与该过程。但是,如果视图控制器动态添加和删除视图,则 Interface Builder 中的静态布局可能无法实现。在这种情况下,视图控制器是控制流程的好地方,因为视图本身通常只有场景中其他视图的有限图片。
如果在 Interface Builder 中取消选中 Autolayout 选项,则可以使用setFrame
in 。viewDidLoad
如果您需要使用自动布局,您需要在viewDidLayoutSubviews:
.
关于“要求视图展示自己对我来说没有意义。视图无权说出它们应该去哪里。这就是控制器的角色,不是吗?”。我认为答案通常是否定的。它是父视图(不是视图控制器),它通常扮演布置它自己的子视图的角色。它通过使用 autoresizingMask 或 autolayout(仅限 iOS 6)来实现。或者您可以通过覆盖-layoutSubviews
父视图的方法以编程方式进行布局。
当然,就像 Imre 提到的那样,控制器也可以通过覆盖来参与布局过程- (void)viewDidLayoutSubviews
。当我不想继承视图控制器的顶级视图以保持简单时,我经常使用这种方法。
最后,我发现这篇文章非常有用。即使有一些小错误,这篇文章也提供了视图布局过程的大图。