【发布时间】:2015-11-26 15:29:42
【问题描述】:
首先,我要提一下,这主要是一个效率问题。
在viewWillAppear 太早而viewDidAppear 太晚(视图已经可见)的情况下,关于在哪里进行帧计算的讨论很多。
常见的答案是在viewDidLayoutSubviews 中进行帧计算。问题是,它被多次调用。更糟糕的是,最准确的调用,即所有帧都有其最终大小的调用是最后一个调用。据我所知,没有办法知道哪个呼叫是最后一个呼叫。
我们曾经有一个'framesAreSet'标志(初始化为假)和一个检查,如果帧不为零(类似于self.view.frame.size.width != 0)并且'framesAreSet'为假,它会进入,转动标志并只计算一次。比如:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if (self.view.frame.size.width != 0 && !framesAreSet)
{
framesAreSet = true;
//Calculate frames here
}
}
这看起来没问题,但实际上,检查 self.view.frame.size.width != 0 之类的内容不保证确实设置了框架。 viewDidLayoutSubviews 将在之后被调用这一事实表明某些帧未设置为其最终状态。
如果有viewCompleteLayoutSubviews 那就太好了。当所有框架都已设置且视图尚不可见时,对于完成“一次性”框架计算的最佳方法有什么想法吗?
(这可能是视图不使用 NSConstraints 的问题)
【问题讨论】:
-
为什么
viewDidLayoutSubviews被多次调用是个问题?你面临什么问题? -
你有机会更新
self.view的边界吗?如果是这样,那是你的问题。 -
@rmaddy 冗余不是好的编码习惯。假设您有一个复杂的 ViewController,在代码中添加了许多子视图(实际上大部分是在代码中创建的)并为设置框架进行了许多计算。事实上,想象一下“繁重”的计算调用次数与添加子视图的次数一样多。请注意,除了最后一个之外,所有内容都是多余的。有时“它有效”还不够好。
-
所以您的问题严格来说是效率问题之一。你应该在你的问题中说清楚。我过去做过的一件事是跟踪
self.view.frame.size和内部viewDidLayoutSubviews我只在上次调用后大小发生变化时才进行计算。 -
@rmaddy 更新了问题。谢谢。