如何找到UIViewController视图的确切帧?

5

什么情况下可以知道UIViewController的视图的确切大小?

问题

我有一个多行的UILabel,其框架取决于其文本和父视图的宽度。鉴于我需要将其他视图放置在UILabel下面,因此将其框架准确地覆盖文本所占用的空间非常重要。

我当前是这样计算大小的:viewDidLoad

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

问题在于,当UIViewController被用作模态表单或弹出窗口时,父视图的宽度会发生变化。如果使用autoresizingMask,则UILabel的框架会相应地调整,但它不再完全适合文本。
在知道UIViewController视图的确切大小的情况下,我该在哪里计算这个UILabel的框架?
调试工作
打印self.view.frame的结果,当将UIViewController显示为模态表单(UIModalPresentationFormSheet)时,如下所示:
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方法手动定位每个控件。 - Mike Weller
4个回答

2
这是因为您的UIViewController的根视图使用了自动调整大小的掩码(autoresizingMask)。我认为除非您重写根视图的 'layoutSubviews' 方法,否则没有“完美的时间”来检测您的UIViewController根视图的大小。
如果您不想让您的视图自动调整大小,请不要使用自动调整大小功能,并手动设置大小,这样它将始终是您期望的相同大小。
如果您不确定您的根视图使用了哪种自动调整大小掩码,NSLog就是您的好帮手。

1

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

另一种方法是子类化你的 UIView 并在其中重写 layoutSubviews,根据内容排列子视图。然后,每当更新标签的内容时,你将不得不从你的视图控制器调用 [self.view setNeedsLayout]。如果视图大小会改变,系统将自动调用它,因此你应该可以解决问题。


你确定在viewWillAppear中应该知道这个frame吗?我查看了文档,上面并没有提到。 - hpique
此外,覆盖layoutSubviews似乎是一个解决方案。然而,我希望有一些更简单的方法来解决像调整UILabel大小这样微不足道的问题。 - hpique
@hgpc 不是很确定,但我的直觉告诉我应该是这样的... 这并不是太困难了...! 它只是一个你必须要有的额外类。 - joerick

0

尝试使用以下代码查询标签大小:

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

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


你可以再详细说明一下吗?我已经定义了标签的宽度,所以我不确定它如何提供视图的实际宽度。 - hpique

0
尝试使用viewWillAppear。在视图即将显示之前,没有不知道大小的理由。

当视图以模态表单形式显示时,viewWillAppear 不会提供正确的大小。 - hpique

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