有人能对UIView's
setNeedsLayout
、layoutIfNeeded
和layoutSubviews
方法之间的关系给出一个明确的解释吗?和一个示例实现,其中所有这三个都将使用。谢谢。
让我感到困惑的是,如果我向自定义视图发送一条setNeedsLayout
消息,它在此方法之后调用的下一个内容是layoutSubviews
,直接跳过layoutIfNeeded
。从文档中,我期望流程是setNeedsLayout
>导致layoutIfNeeded
被调用>导致layoutSubviews
被调用。
发布于 2012-12-20 07:15:27
我想补充一下n8grey的回答,在某些情况下,您需要先调用setNeedsLayout
,然后调用layoutIfNeeded
。
例如,假设您编写了一个扩展UIView的自定义视图,其中子视图的定位很复杂,并且不能使用autoresizingMask或iOS6 AutoLayout完成。自定义定位可以通过覆盖layoutSubviews
来完成。
例如,假设您有一个自定义视图,该视图具有一个contentView
属性和一个edgeInsets
属性,该属性允许在contentView周围设置边距。layoutSubviews
将如下所示:
- (void) layoutSubviews {
self.contentView.frame = CGRectMake(
self.bounds.origin.x + self.edgeInsets.left,
self.bounds.origin.y + self.edgeInsets.top,
self.bounds.size.width - self.edgeInsets.left - self.edgeInsets.right,
self.bounds.size.height - self.edgeInsets.top - self.edgeInsets.bottom);
}
如果希望在更改edgeInsets
属性时能够以动画形式显示帧更改,则需要按如下所示覆盖edgeInsets
设置器,并调用setNeedsLayout
,然后调用layoutIfNeeded
- (void) setEdgeInsets:(UIEdgeInsets)edgeInsets {
_edgeInsets = edgeInsets;
[self setNeedsLayout]; //Indicates that the view needs to be laid out
//at next update or at next call of layoutIfNeeded,
//whichever comes first
[self layoutIfNeeded]; //Calls layoutSubviews if flag is set
}
这样,在执行以下操作时,如果更改了动画块中的edgeInsets属性,则将对contentView的帧更改进行动画处理。
[UIView animateWithDuration:2 animations:^{
customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];
如果不在setEdgeInsets方法中添加对layoutIfNeeded的调用,动画将无法工作,因为layoutSubviews将在下一个更新周期被调用,这等同于在动画块外部调用它。
如果只在setEdgeInsets方法中调用layoutIfNeeded,则不会发生任何事情,因为没有设置setNeedsLayout标志。
https://stackoverflow.com/questions/2807137
复制相似问题