如何找出 UIViewController 视图的确切框架?
什么时候可以知道 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
那是因为你的 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.
这看起来像一个错误,该值应该在 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.尝试使用此方法查找标签大小,
而不是使用视图的宽度,而是在约束大小中使用标签的宽度。这应该在视图控制器的 viewDidLoad、viewDidApper 方法中可用。
Try this for finding the label size,
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.
尝试viewWillAppear。在视图即将显示之前没有理由不知道尺寸
try viewWillAppear. There is no reason for not knowing the size before the the view is about to shown