如何找出 UIViewController 视图的确切框架?

Posted

技术标签:

【中文标题】如何找出 UIViewController 视图的确切框架?【英文标题】:How to find out the exact frame of a UIViewController's view? 【发布时间】:2011-08-16 10:00:21 【问题描述】:

什么时候可以知道UIViewController 视图的确切大小?

问题

我有一个多行UILabel,其框架取决于其文本和父视图的宽度。鉴于我需要将其他视图低于UILabel,使其框架完全覆盖文本空间非常重要。

我目前在viewDidLoad上这样计算大小:

labelSize = [text sizeWithFont:font constrainedToSize:CGSizeMake(self.view.frame.size.width, MAX_HEIGHT)];

问题是当UIViewController 用作模态表单或弹出框时,父视图的宽度会发生变化。如果我使用autoresizingMask,UILabel 的框架会相应调整,但它不再适合文本。

知道UIViewController's 视图的确切大小,我在哪里可以计算此UILabel 的框架?

调试工作

这是在将UIViewController 显示为模式表单 (UIModalPresentationFormSheet) 时打印 self.view.frame 的结果。

viewDidLoad: (0.000000;0.000000;320.000000;480.000000)
viewWillAppear: (0.000000;0.000000;768.000000;960.000000)
afterDelay: (0.000000;0.000000;540.000000;576.000000)

产生上述输出的代码:

- (void)viewDidLoad 
    [super viewDidLoad];
    [Utils logFrame:self.view.frame tag:@"viewDidLoad"];


- (void) viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];
    [Utils logFrame:self.view.frame tag:@"viewWillAppear"];
    [self performSelector:@selector(afterDelay) withObject:nil afterDelay:0.1];


- (void) afterDelay 
    [Utils logFrame:self.view.frame tag:@"afterDelay"];

【问题讨论】:

如果 autoresizingMask 没有达到你想要的效果,你将不得不创建一个 UIView 子类并实现 layoutSubviews 方法来手动定位所有内容。 【参考方案1】:

那是因为你的 UIViewController 的根视图使用了 autoresizingMask。我不认为有一个“完美的时机”来检测你的 UIViewController 的根视图的大小,除非你覆盖你的根视图的 'layoutSubviews' 方法。

如果您不希望视图自动调整大小,请不要使用自动调整大小并自行设置大小,它将始终与您预期的大小相同。

如果你不确定你的根视图使用的是什么类型的 autoresizingMasks,NSLog 是你的好朋友。

【讨论】:

【参考方案2】:

这看起来像一个错误,值应该在 viewWillAppear 中是已知的。

另一种方法是将您的 UIView 子类化并覆盖 layoutSubviews 以根据内容排列子视图。然后,每次更新标签的内容时,您都必须从视图控制器调用[self.view setNeedsLayout]。如果视图调整大小,系统将调用它,所以你应该已经涵盖了。

【讨论】:

您确定在 viewWillAppear 中应该知道该框架吗?我检查了文档,它没有说明任何内容。 另外,覆盖 layoutSubviews 看起来可能是一个解决方案。然而,我希望能少一些.. 解决这样一个微不足道的事情,比如调整 UILabel 的大小。 @hgpc 不确定,但我的直觉告诉我它应该是....这不是令人生畏...!这只是你必须参加的额外课程。【参考方案3】:

试试这个找出标签大小,

labelSize = [text sizeWithFont:font constrainedToSize:CGSizeMake(self.label.frame.size.width, MAX_HEIGHT)];

在约束大小中使用标签的宽度,而不是使用视图的宽度。这应该在视图控制器的 viewDidLoad、viewDidApper 方法中可用。

【讨论】:

您能详细说明一下吗?我定义了标签的宽度,所以我不确定它如何为我提供视图的真实宽度。【参考方案4】:

试试 viewWillAppear。在视图即将显示之前没有理由不知道大小

【讨论】:

viewWillAppear 至少在视图显示为模式表单时不提供正确的大小。

以上是关于如何找出 UIViewController 视图的确切框架?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UIViewController 作为子视图添加到 UIViewController(RootViewController)?

如何从 UIViewController 填充表格视图

如何从模态视图推送 UIViewController

如何从 viewController 的视图中呈现 UIViewController

如何访问呈现模态视图的 UIViewController 类/类名?

如何在 UIScrollview 中触发 UIViewcontroller 视图的旋转事件