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

Mar*_*Him 5 iphone objective-c uiviewcontroller uiview ios

试着打破我现在有一段时间的问题

背景

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

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

- (UIImage *)calculatedImageForRect:(CGRect)imageRect
Run Code Online (Sandbox Code Playgroud)

问题

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

对于像iPhone6 plus这样具有不同屏幕分辨率的设备,这一点尤为有趣

显然,viewDidLoad框架没有正确设置.此时,帧被设置为故事板的预览 - 例如,用于表示IPhone5分辨率的设置.同样如此viewWillAppear.这里的帧例如是(10,10,300,100)< - 让我们把它称为错误帧

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

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

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

当然,我可以[UIScreen mainScreen]通过使用UIImageView的尾随和前导约束来从分辨率计算出正确的帧,但它感觉很脏.

alg*_*gal 9

您不能使用的原因viewDidLayoutSubviews是,正如您所说,它可能不止一次被调用.这也是如此layoutSubviews.

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

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

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

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

  • 老实说,我没想到它会起作用——但它确实起作用了。我现在在“viewWillAppear:”中调用“layoutIfNeeded”,正如您所描述的,所有子视图随后都会正确布局。谢谢海藻的回答。 (3认同)