【发布时间】:2013-12-24 19:10:16
【问题描述】:
似乎viewDidLayoutSubviews 在视图上调用layoutSubviews 之后立即被调用,在该视图的子视图上调用layoutSubviews 之前。有没有办法知道何时在视图上调用了 layoutSubviews 及其所有也需要更新其布局的子级?
【问题讨论】:
标签: ios objective-c uiview uiviewcontroller layoutsubviews
似乎viewDidLayoutSubviews 在视图上调用layoutSubviews 之后立即被调用,在该视图的子视图上调用layoutSubviews 之前。有没有办法知道何时在视图上调用了 layoutSubviews 及其所有也需要更新其布局的子级?
【问题讨论】:
标签: ios objective-c uiview uiviewcontroller layoutsubviews
您不必知道子视图的子视图是否更新了它们的布局:这听起来耦合太紧了。此外,每个子视图可能会以不同的方式处理它们各自子视图的排列,并且可能根本不需要(不需要)为其子视图调用layoutSubviews。你应该只需要知道你的直接子视图。您应该或多或少地将它们视为黑匣子,而不关心它们是否有自己的子视图。
【讨论】:
正如@Johannes Fahrenkrug 所说,您应该“将它们视为黑匣子”。但按照我的理解,那是因为Cocoa不能承诺。
如果您确实需要在所有子视图完成布局工作时收到通知,这里有一个核心示例可能会解决您的问题。我也不保证它会在任何情况下都有效。
- (void) layoutSubviewsIsDone{
// Your code here for layoutSubviews is done
}
// Prepare two parameters ahead
int timesOfLayoutSubviews = 0;
BOOL isLayingOutSubviews = NO;
// Override the layoutSubviews function
- (void) layoutSubviews{
isLayingOutSubviews = YES; // It's unsafe here!
// you may move it to appropriate place according to your real scenario
// Don't forget to inform super
[super layoutSubviews];
}
// Override the setFrame function to monitor actions of layoutSubviews
- (void) setFrame:(CGRect)frame{
if(isLayingOutSubviews){
if(frame.size.width == self.frame.size.width
&& frame.size.height == self.frame.size.height
&& frame.origin.x == self.frame.origin.x
&& frame.origin.y == self.frame.origin.y
&& timesOfLayoutSubviews ==self.subviews.count){
isLayingOutSubviews = NO;
timesOfLayoutSubviews = 0;
[self layoutSubviewsIsDone]; // Detected job done, call your function
}else{
timesOfLayoutSubviews++;
}
}
【讨论】: