为什么我必须在viewDidLoad中手动设置视图的框架? [英] Why am I having to manually set my view's frame in viewDidLoad?

查看:110
本文介绍了为什么我必须在viewDidLoad中手动设置视图的框架?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在UITabBarController中使用UINavigationController进行了非常基本的设置。我想以编程方式布局该navcontroller的rootViewController视图,但是当我查看viewDidLoad中的self.view.frame时,我得到了这个(例如 landscape ):

I have a pretty basic setup with a UINavigationController inside a UITabBarController. I'm wanting to programmatically layout the view of the rootViewController of that navcontroller, but when I look at self.view.frame inside viewDidLoad, I get this (in landscape, for example):

1. view frame: {{20, 0}, {748, 1024}} // looks like an odd portrait mode

然后我自动旋转到肖像,我得到了这个:

Then I autorotate to Portrait, and I get this:

2. view frame: {{0, 0}, {768, 911}}

然后当我回去到横向,框架现在是这样的:

Then when I go back to Landscape, the frame is now this:

3. view frame: {{0, 0}, {1024, 655}}

进一步的自动旋转事件将帧值#2&之间的触发器#3。

And further autorotation events will flip-flop between frame values #2 & #3.

为了解决#1的奇怪现象,我目前正在viewDidLoad中执行此操作:

To get around the weirdness of #1, I'm currently doing this in viewDidLoad:

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    self.view.frame = CGRectMake(0, 0, 768, 911);
} else {
    self.view.frame = CGRectMake(0, 0, 1024, 655);
}

我觉得我在这里显然缺少一些东西。为什么视图的默认框架在自动旋转回相同方向时与框架不匹配?视图框架是否未设置为初始方向?非常困惑...

I feel like I'm obviously missing something here. Why would the default frame of the view not match the frame when it autorotates back to the same orientation? Does the view frame not get set to the initial orientation? Very confused...

我应该提到上述所有内容,包括我的kludgy hack,都没有在视觉上改变任何东西。我有黑客的原因是,当我将我的子视图布局到这个视图中时,它们将基于我期望它们的位置,这是导航栏下方的左上角。

I should mention that none of the above, including my kludgy hack, changes anything visually. The reason I have the hack is so that when I layout my subviews into this view, they'll be based off of where I expect them to be, which is the top left corner just under the navigation bar.

我做错了什么?

更新:关闭视图更改结果#1上的所有自动调整内容:

UPDATE: turning off all the autosizing stuff on the view changes result #1 to be:

view frame: {{0, 0}, {748, 1024}}

这似乎有点接近,但仍然不匹配#3。

That seems a tiny bit closer, but still not matching #3.

推荐答案

不保证viewDidLoad中的帧与最终显示视图时的帧相同。 UIKit会根据显示的上下文调整视图控制器视图的框架,然后再显示它。大小取决于界面方向和任何可见导航栏,标签栏,工具栏或状态栏的尺寸(其本身的高度可以更改,例如当您打电话时)。

The frame is not guaranteed to be the same in viewDidLoad as it will be when the view is eventually displayed. UIKit adjusts the frame of your view controller's view prior to displaying it, based on the context in which will appear. The size is determined based on interface orientation and the dimensions of any visible navigation bar, tab bar, toolbar, or status bar (which itself has a height that can change, e.g. when you're on a phone call).

它有助于理解加载和显示视图控制器视图时会发生什么:

It helps to understand what happens when a view controller's view is loaded and displayed:


  1. Something第一次访问视图控制器的视图属性。这可能发生在您自己的代码中,或者在UIKit中,以响应用户操作,例如选择选项卡。

  1. Something accesses your view controller's view property for the first time. This may occur in your own code, or in UIKit in response to a user action like selecting a tab.

UIKit通过调用懒惰加载视图控制器的视图 loadView 如果已定义,或者从 initWithNibName:bundle:中指定的NIB加载视图。如果两者都不存在,UIKit只会加载一个空视图。

UIKit lazy-loads your view controller's view by calling loadView if it's defined, or by loading the view from the NIB that was specified in initWithNibName:bundle:. If neither exists, UIKit just loads an empty view.

UIKit调用 viewDidLoad 一旦视图及其子视图已完全加载。 此时视图的框架将是在NIB中设置的任何内容,或者在 loadView 中。

UIKit calls viewDidLoad once the view and its subviews have been fully loaded. At this point the view's frame will be whatever it was set to in the NIB, or in loadView.

有人要求UIKit显示你的视图控制器的视图。同样,这可能是一个用户操作,如点击选项卡,或代码中的显式方法调用,如 pushViewController:animated: presentModalViewController:animated :

Something calls for UIKit to display your view controller's view. Again, this may be a user action like tapping on a tab, or an explicit method call in your code like pushViewController:animated: or presentModalViewController:animated:.

如上所述,UIKit会根据视图的上下文调整视图大小。

UIKit resizes the view based on the context in which it will be presented, as described above.

UIKit调用 viewWillAppear: 框架现在应该是将显示的尺寸。 (?)编辑:这可能不再是真的。请参阅以下评论。

UIKit calls viewWillAppear:. The frame should now be the size that will be displayed. (?) This may no longer be true. See the comments below.

UIKit会显示视图,包含或不包含动画。

UIKit displays the view, with or without animations.

UIKit调用 viewDidAppear:

正如您所看到的,如果您需要知道视图框架的大小, viewWillAppear:是您唯一的机会。请记住,视图出现后,由于各种原因(包括旋转事件或状态栏高度的更改),此大小可能会更改。因此,为每个子视图提供适当的autoresizingMask非常重要,以确保布局可以针对边界的任何更改进行正确调整。

As you can see, if you need to know the size of your view's frame before it gets presented, viewWillAppear: is your one and only opportunity. Just remember that this size may change after the view appears for various reasons, including rotation events or changes in status bar height. For this reason, it's important to give every subview an appropriate autoresizingMask, to ensure that the layout can adjust itself properly for any change in bounds.

如果您希望构建手动查看层次结构,建议的位置是在loadView中。由于您在此方法中自己构建视图,因此可以将其框架初始化为您想要的任何内容。你选择的大小并不重要,因为无论如何UIKit很可能会改变它。只需确保正确设置autoresizingMasks。

If you wish to build your view hierarchy manually, the recommended place to do so is in loadView. Since you construct the view yourself in this method, you can initialize its frame to whatever you'd like. The size you choose doesn't matter much, since UIKit is likely to change it on you anyway. Just make sure you set your autoresizingMasks appropriately.

这篇关于为什么我必须在viewDidLoad中手动设置视图的框架?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆