在我的自定义视图(UIScrollView
子类)中,我正在调用setNeedsLayout
以响应"重新加载数据"事件(由外部源触发)。大部分时间这都正常工作,并且在下一个视图布局循环发生时调用layoutSubviews
。但有时候,layoutSubviews
不会被调用!到目前为止,我一直生活在"某些知识和#34; setNeedsLayout
总是触发layoutSubviews
。显然我错了。我甚至尝试在layoutIfNeeded
之后致电setNeedsLayout
,但仍然没有成功。
显然,我想解决我的特殊问题。另一方面,我想提高我对iOS视图布局过程的理解,所以我正在以一般方式制定我的问题:你知道任何可能阻止在layoutSubviews
之后被调用的条件吗? {1}}被称为?关注setNeedsLayout
的答案非常受欢迎,因为那是我遇到麻烦的地方。
我在iOS 7.1上,使用Xcode 5.1.1。关于我的自定义滚动视图的实现的注意事项:
UIScrollView
的容器视图,其总大小与滚动视图内容大小相同UIView
实施通过手动计算子视图将自定义子视图放入容器视图中。帧以下是layoutSubviews
实现的方式:
reloadData
最后但并非最不重要的是,以下是我所做的一些观察:
- (void) reloadData
{
// Iterates through an internal array that holds the subviews,
// then empties the array. Subviews are deallocated at this
// point.
[self removeAllSubviewsFromContainerview];
self.contentOffset = CGPointMake(0, 0);
// I verified that the content size is always greater than
// CGSizeZero (both width and height)
CGFloat contentWidth = [self calculateNewContentWidth];
self.contentSize = CGSizeMake(contentWidth, self.frame.size.height);
// Here is the problem: Sometimes this triggers layoutSubviews,
// sometimes it does not.
[self setNeedsLayout];
// Adding the following line for debugging purposes does not
// help, making it clear that setNeedsLayout has no effect.
// [self layoutIfNeeded];
}
。如果这两个值没有改变,layoutSubviews
在我的特定情况下会被 调用。我首先假设此观察是layoutSubviews
的一般工作原则,即除非内容偏移或内容大小发生变化,否则UIScrollView
通常不会调用layoutSubviews
。然而,当我写了几个最小的项目时,我没有重现这个假设的#34; general"行为 - 在这些项目中UIScrollView
始终按预期调用,无论内容偏移量或内容大小是否发生变化。layoutSubviews
实例而不是我自己的自定义子视图,则始终按预期调用layoutSubviews
UILabel
,但会在自定义子视图中替换自动布局'通过手动框架计算实施最后两个观察结果让我相信Auto Layout以某种方式参与其中,但我真的不知道这会如何影响layoutSubviews
的工作方式。