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

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

问题描述

我有一个非常基本的设置,在 UITabBarController 中有一个 UINavigationController.我想以编程方式布局该导航控制器的 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...

我应该提到,以上所有内容,包括我的笨拙黑客,都不会在视觉上改变任何东西.我有 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. 有东西第一次访问你的视图控制器的 view 属性.这可能会发生在您自己的代码中,也可能发生在 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:.如果两者都不存在,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 显示视图,带或不带动画.

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天全站免登陆