如何在ViewController的viewDidAppear之前确定UIView大小

时间:2015-09-02 15:51:31

标签: ios objective-c iphone uiview uiviewcontroller

试图解决我现在有一段时间的问题

背景

让我们假设我尝试计算一个完全适合UIImageView的UIImage,它在故事板中配置了约束。

imageView的内容不应该填充/方面适合...但完全适合框架。 因此我的viewController中有一个方法

- (UIImage *)calculatedImageForRect:(CGRect)imageRect

问题

我想确保,只要视图变得可见,imageView就已包含正确的图像,因此在简单的推送过渡期间也是如此。 另外,我不想多次生成UIImage,因为它相对昂贵。

对于像iPhone6 plus这样具有不同屏幕分辨率的设备

,这一点尤其有趣

显然,在viewDidLoad时帧数设置不正确。此时,帧被设置为故事板的预览 - 例如用于表示IPhone5分辨率的设置。 viewWillAppear也是如此。 这里框架将是例如是(10,10,300,100)< - 让我们称之为错误的框架

viewDidAppear帧正确(10,10,394,100)= 正确帧< - 而不是320点宽度,iPhone6Plus有414点。然而,这里为时已晚,因为视图已经可见并且设置图像会导致闪烁(空图像>新生成的图像)​​。

我知道使用宽度的正确时间是viewDidLayoutSubviews,首先使用错误帧至少调用一次,然后使用进行一次调用正确帧。 但正如我所说,我不想多次生成图像,所以这就是困境:

如何在可见之前确定右框架

当然,我可以通过使用尾随&分辨率从[UIScreen mainScreen]分辨率计算出正确的帧。 UIImageView的主要限制,但它感觉很脏。

1 个答案:

答案 0 :(得分:9)

您无法使用viewDidLayoutSubviews的原因是,正如您所说,可能会多次调用它。 layoutSubviews也是如此。

这是为什么?一个原因是因为基于约束的布局是一个迭代过程,可能涉及多次通过。例如,假设我强制视图V的布局,其在其视图层次结构中包含子视图W,其包含子视图X.X的布局的第一个自动布局计算可以改变约束,然后需要重新计算W然后需要重新计算X.这基本上不同于具有自动调整大小掩码的布局,它是自上而下的,因此外部视图总是指示其子视图的布局。

然而,我相信(但并非100%肯定),如果所有布局代码都正确实现,那么这些多个布局通道都应该在运行循环的一圈内发生。也就是说,当您通过调用layoutIfNeeded来强制在V上布局来启动此过程时,您可以确保所有自动布局布局传递W和X已完成,一次{{1返回。不需要布局"或者"需要更新约束"标志将被留下脏,等待运行循环的下一轮完成工作。

这可能指向您的解决方案。如果强制层次结构中的顶级视图的早期布局(例如正在转换到的视图控制器的根视图),那么当该布局传递完成时,layoutIfNeeded将具有正确的框架,并且您可以使用该帧生成图像。

基本上,你不是在最后一刻做布局,而是强迫它提前完成。然后,您可以知道它何时完成,因为您已启动它,并且可以通过等待UIImageView退出来查看该过程的结束。然后你可以观察你关心的结果值。