什么条件可以阻止在setNeedsLayout之后调用layoutSubviews?

时间:2014-05-29 15:52:20

标签: ios uiscrollview autolayout

问题

在我的自定义视图(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的工作方式。

0 个答案:

没有答案