2

我有以下设置

  • XIB 文件只有横向视图。此视图连接到我的控制器
  • 此视图上有一个标签连接到IBOutlet UILabel* label
  • 这个标签是这样配置的(它占据了屏幕的整个宽度)。 在此处输入图像描述
  • 我重写了 viewWillAppear 并执行此操作(以获取标签的大小)。
-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    CGRect rect = _labelTitleLand.frame;
}

奇怪的事情(我不明白)。它在纵向启动时(在 iPad 上)返回 size = (width 768, height 21),这是正确的。

它在横向启动时返回 size = (width 741 height 21)。这很奇怪。我预计它将返回宽度 1024,高度 21 用于横向。

我的印象是,在 viewWillAppear 的那一刻,所有控件的大小都已经计算过了。

更新 1

如果我在 viewDidAppear 上检查 labelTitleLand.frame,那么它会返回正确的结果。但是,我不喜欢这样,因为我想做一些影响视图绘制方式的动作(基于这个大小)。在这种情况下,如果我将在 viewDidAppear 上执行此操作,据我所知,将会有可见的重绘。

4

2 回答 2

8

在获得实际的最终帧之前,必须完成视图层次结构的布局。

所以你应该检查框架viewDidLayoutSubviews,它仍然是在视图层次结构被实际绘制之前。如果您需要在此处进行更改,您可以在不引起任何重绘的情况下进行。

viewWillAppear为时过早,因为这是在您的自动调整掩码(和/或自动布局约束)产生效果之前。

于 2013-08-06T00:41:47.700 回答
0

这似乎是一个与在运行时实际调用方法有关的问题。

我解决了类似的情况

[self performSelector:@selector(checkMethod) withObject:nil afterDelay:0.1];

在 viewWillAppear 中,然后:

- (void)checkMethod
{
    rect = _labelTitleLand.frame;
}

这为您的应用程序提供了设置自己的框架所需的时间。它不是那么优雅,看起来像是一种解决方法,但它非常有效。

您还可以尝试在 viewWillAppear 中强制作为 UILabel 容器的 UIView 的框架,如下所示:

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    self.view.frame = CGRectMake(0.0f, 0.0f, 1024.0f, 768.0f);

    CGRect rect = _labelTitleLand.frame;
}

但第一种解决方案更可靠,通常不会出现延迟。

于 2013-08-06T00:43:09.693 回答