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

发布于 2024-11-29 22:54:52 字数 1343 浏览 2 评论 0原文

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

问题

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

我目前在 viewDidLoad 上计算的大小如下:

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

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

在知道 UIViewController 视图的确切大小的情况下,我可以在哪里计算此 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"];
}

When is it possible to know the exact size of a UIViewController's view?

The Problem

I have a multi-line UILabel whose frame depends of its text and the width of the parent view. Given that I need to position other views below the UILabel, it's important to make its frame cover exactly the space of the text.

I currently calculate the size like this on viewDidLoad:

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

The problem is that the width of the parent view changes when the UIViewController is used as a modal form sheet or a popover. If I use autoresizingMask the frame of the UILabel is adjusted accordingly, but it no longer is an exact fit for the text.

Where can I calculate the frame of this UILabel knowing the exact size of the UIViewController's view?

Debugging Efforts

This is the result of printing self.view.frame when showing the UIViewController as a modal form sheet (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)

The code that produces the above output:

- (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"];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

云淡月浅 2024-12-06 22:54:52

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

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

如果您不确定您的根视图使用哪种 autoresizingMasks,NSLog 是您的朋友。

That's because your UIViewController's root view is using autoresizingMask. I don't think there is a "perfect timing" to detect the size of your UIViewController's root view unless you override your root view's 'layoutSubviews' method.

If you don't want your view to be automatically resized, just don't use autoresizing and set the size by yourself, it will always be the same size you expected.

If you are not sure what kind of autoresizingMasks your root view is using, NSLog is your friend.

菊凝晚露 2024-12-06 22:54:52

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

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

This looks like a bug, the value should be known in viewWillAppear.

The alternative is to subclass your UIView and override layoutSubviews there to arrange the subviews based on content. You'll then have to call [self.view setNeedsLayout] from your view controller every time you update the contents of the label. The system will call it if the view resizes, so that should have you covered.

月依秋水 2024-12-06 22:54:52

尝试使用此方法查找标签大小,

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

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

Try this for finding the label size,

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

Instead of using the view's width, use the label's width in the constrain size. This should be available in the viewDidLoad, viewDidApper methods of the view controller.

脱离于你 2024-12-06 22:54:52

尝试viewWillAppear。在视图即将显示之前没有理由不知道尺寸

try viewWillAppear. There is no reason for not knowing the size before the the view is about to shown

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文