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

标签 ios objective-c iphone uiview uiviewcontroller

试图解决我现在遇到的一个问题

背景

假设我尝试计算一个应该完全适合 UIImageView 的 UIImage,该 UIImageView 在 Storyboard 中使用约束进行布局。

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

- (UIImage *)calculatedImageForRect:(CGRect)imageRect

问题

我想确保一旦 View 可见,imageView 就已经包含正确的图像,在简单的推送转换期间也是如此。 此外,我不想多次生成 UIImage,因为它相对昂贵。

对于像 iPhone6 plus 这样具有不同屏幕分辨率的设备,这变得特别有趣

显然在 viewDidLoad 中,帧设置不正确。在这一点上,框架被设置为 Storyboard的预览 - 例如表示 iPhone5 分辨率的设置。 viewWillAppear 也是如此。 这里的框架例如是 (10,10,300,100) <-- 我们称它为错误帧

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

我知道使用宽度的正确时间是 viewDidLayoutSubviews,它首先用 wrong-frame 至少调用一次,然后在某一点用正确的框架。 但正如我所说,我不想多次生成图像,所以这是一个难题:

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

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

最佳答案

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

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

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

这可能会为您的解决方案指明方向。如果你在层次结构中强制顶层 View 的早期布局(例如你正在转换到的 View Controller 的 Root View ),那么当布局传递完成时,UIImageView 将有一个正确的框架,您可以使用该框架生成图像。

本质上,不是在最后可能的时刻进行布局,而是强制它更早完成。然后您可以知道它何时完成,因为您启动了它,并且可以通过等待 layoutIfNeeded 退出来看到该过程的结束。然后您可以观察到您关心的结果值。

关于ios - 如何在其 ViewController 的 viewDidAppear 之前确定 UIView 大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32357679/

相关文章:

iphone - iphone 错误 : Assertion failed: (s->stack->next ! = NULL),函数 CGGStackRestore,文件 Context/CGGStack.c,第 116 行

来自按钮的 IOS segue(推送,模态或自定义)不起作用

ios 核心数据 : make sure object is deleted from data source

ios - 使用一个 UIWebView 加载具有不同按钮的多个 URL -- iOS Swift

iphone - 正确的媒体查询语法 CSS Iphone

objective-c - NSDate 和 NSDateFormatter 返回无效的 CFStrinfRef

iOS crasher:CFNetwork HTTPReadFilter::doPlainRead(StreamReader*, unsigned char*, long, CFStreamError*, unsigned char*)

python - DeviceCheck:无法验证授权 token

iphone - 在 App Purchase 链接中找不到 iTunes 连接我的应用程序

objective-c - 使用 CGPoint 和 CATransform3D 在一条线上找到一个新点?