确定loadView中正确的大小

23

如何在loadView中确定正确的视图大小?

在我使用UIViewController被推到UINavigationController,或UITabBarController出现时,不同的情况需要注意可用屏幕区域的变化,如果我硬编码值则会不一致。

在loadView被调用时,我想知道如何确定容器视图的大小,以添加我的子视图。

我查看了UIViewController指南,苹果公司使用UIScreen mainScreen applicationFrame,但在他们的示例中这样做是因为他们正在制作一个全屏应用程序。

我看到有些答案在这里,但没有解决如何以一致的方式进行此操作的问题。

感谢您所提供的任何帮助。


1
为什么不使用自动调整大小掩码? - Krumelur
4个回答

16

您不需要知道确切的大小。视图控制器不应该自己调整大小,这是其父视图的责任。只需创建一个 UIView ,使用 [[UIView alloc] init] 即可确认,这是由苹果 UIKit 工程师安迪·马图舍克在 Twitter 上确认的:https://twitter.com/andy_matuschak/status/365227892151558144


3
这是正确的,我的先前回答(现已删除)实际上是错误的。你也可以使用self.view = [[UIView alloc] initWithFrame:CGRectZero];. 如果你不使用自动布局,请不要忘记设置self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - Tafkadasoh
如果原始框架大小为0,则自动调整大小掩码实际上不起作用,因为0 * x = 0 :)。关键是您不需要调整视图控制器的大小:父VC(或UIWindow(如果它是主要的))将为您执行此操作。 - Javier Soto

13
- (void) loadView {
     //self.wantsFullScreenLayout = YES; //could add this for translucent status bars
     UIView *view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
     self.view = view;
}

根据苹果的“视图控制器编程指南”,创建视图的步骤如下:

  1. 创建一个根视图对象,使其大小适应屏幕。 根视图作为与视图控制器关联的所有其他视图的容器。通常您会定义此视图的框架来匹配应用程序窗口的大小,而应用程序窗口本身应填充整个屏幕。但是,视图控制器也会根据需要调整框架大小以适应各种视图的出现,例如系统状态栏、导航栏或选项卡栏。 您可以使用通用的UIView对象、您定义的自定义视图或任何其他可以缩放以填充屏幕的视图。

它还有一个类似于我上面写的示例。


2
viewController在loadView中没有view属性 - 如果我调用[super loadView],会创建一个视图,但我的想法是自己创建一个。 - RickiG
1
  • (void) loadView { UIView *containerView = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease]; NSLog(@"%@", NSStringFromCGRect(containerView.frame)); self.view = containerView; } 当将viewController加载到tabBarController中时,尝试以上代码会在屏幕上记录{{0, 20}, {320, 460}},这不是可用内容大小。这就是让我担心的地方 - Apple推荐这种方法,在这里有10多个问题...没有人知道如何做吗?
- RickiG
1
我创建了一个示例应用程序并进一步研究了这个问题。我认为你想要的功能,不能直接得到(你可能已经知道了)。UITabBarController和UINavigationController只是专门的视图控制器。loadView: 对此一无所知,也不应该知道 - 因为UIViewController不应与任何专门的版本耦合。UIScreen也不应该知道或与UIViewController耦合。当您在IB中执行此操作时,仍然必须正确调整UIView的大小以适应UITabBarController或UINavigationController上下文... - bandejapaisa
虽然我知道苹果提供了一个这样做的示例,但我认为在self.view中使用initWithFrame是不正确的。你只需要调用init,并信任父视图(或根视图控制器)来设置整个视图控制器的大小。毕竟,在横向和纵向方向上,你有不同的框架尺寸。 - Ben Wheeler
@property(nonatomic,retain) UIView *view; // 如果视图尚未设置,getter 首先会调用 [self loadView]。如果子类重写 setter 或 getter,则必须调用 super。
  • (void)loadView; // 如果子类不使用 nib,则应在此处创建其自定义视图层次结构。不应直接调用。
- Dmitrii Cooler
显示剩余7条评论

0
“正确”的答案可能是创建一个自定义的UIView子类,并在layoutSubviews的重写中完成所有子视图的位置设置。然后将您的子类分配给loadView中的self.view。
但是,使用viewDidLoad添加与self.view大小相同的子视图也可以工作。(尽管您应该准备好这个视图会改变大小。-正确设置autoresizingMasks可能是实现这一点的好方法。)

-1
我制作了一个应用程序,它加载了几个UITextView、UIButtons和一个UISegment控件。在viewWillAppear中,我调用了一个我自己写的resize方法。
这个方法会以编程方式改变UIViewController中所有子视图的大小。这是因为IB中的自动调整大小只有那么好。
在我的calcViewSize函数中,我像这样获取尺寸;
CGFloat width = [[UIScreen mainScreen] applicationFrame].size.width;
CGFloat height = self.view.frame.size.height; //this will retrieve the frame we are drawn into.

然后我遍历要调整大小的UIViewController中的每个子视图,并更改其框架。我在IBOutlets中拥有这些视图的属性,因此我已经知道这些视图是什么。

使用Interface Builder获取尺寸。

最后一点提示:要在IB中更改尺寸,请选择View,选择属性检查器,禁用状态栏,现在在Size Inspector中,您可以调整视图的大小,重新排列子视图,并写下数字以放置在您的代码中。


嗨,eSpecialized,感谢您的建议。我的问题更多是我不使用IB来创建这些视图,而是在loadView中布局它们。如果我使用applicationFrame,我必须测试选项卡栏或导航栏是否存在,并从中计算我的视图。对于每个推送到容器控制器的视图控制器都要这样做,这相当混乱。 - RickiG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接