iOS:确定何时调用了所有子级的LayoutSubView

iOS:确定何时调用了所有子级的LayoutSubView,ios,objective-c,uiview,uiviewcontroller,layoutsubviews,Ios,Objective C,Uiview,Uiviewcontroller,Layoutsubviews,似乎在对视图调用layoutSubviews之后,在对该视图的子视图调用layoutSubviews之前,会立即调用viewDidLayoutSubviews。是否有任何方法可以知道何时对视图及其所有也需要更新布局的子视图调用了layoutSubviews?您不必知道子视图的子视图是否更新了布局:这听起来好像耦合太紧了。此外,每个子视图可能会以不同的方式处理各自子视图的排列,并且可能(不需要)为其子视图调用layoutSubviews。您应该只需要知道您的直接子视图。您应该或多或少地将它们视为黑

似乎在对视图调用
layoutSubviews
之后,在对该视图的子视图调用
layoutSubviews
之前,会立即调用
viewDidLayoutSubviews
。是否有任何方法可以知道何时对视图及其所有也需要更新布局的子视图调用了
layoutSubviews

您不必知道子视图的子视图是否更新了布局:这听起来好像耦合太紧了。此外,每个子视图可能会以不同的方式处理各自子视图的排列,并且可能(不需要)为其子视图调用
layoutSubviews
。您应该只需要知道您的直接子视图。您应该或多或少地将它们视为黑匣子,而不管它们是否有自己的子视图。

正如
@Johannes Fahrenkrug
所说,您应该“将它们视为黑匣子”。但根据我的理解,这是因为可可不能保证

如果您确实需要在所有子视图完成布局工作后收到通知,下面是一个核心示例,它可能会解决您的问题。我也不保证它在任何情况下都能奏效

- (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++;
    }
}

我不在乎视图是否有任何子视图,我只想知道视图的内容何时被完全更新,以及viewDidLayoutSubviews何时被调用子视图中的任何内容尚未更新。@Thayne AFAIK,一个普通的UIView不会提供这些信息,原因如下:当视图的内容“新鲜”时视图不同:UIImageView子类可能从网络异步获取图像,或者自定义“时钟视图”可能每毫秒刷新一次。子视图是黑盒。超级视图可以知道它已经完成了直接子视图的布局,仅此而已。它们的内容是否是最新的,与superview无关。我想,你必须为此做一个自定义实现。我正在使用一个自定义实现。我的具体问题是,一些子视图正在执行异步操作,我需要等待这些操作完成,然后执行其他操作。但是,在didLayoutSubviews中,没有任何子视图操作已排队(在调度组或其他对象中)。我需要某种方法来确保完成操作在我甚至不知道的操作完成之前不会运行。或者等到我真的知道他们。@Thane我想要解决你的问题,你可能需要重新思考你的架构。听起来好像您的视图正在做许多控制器应该做的事情。让控制器执行异步操作,然后让它们告诉您的视图刷新。此外,如果您需要按特定顺序运行某些异步操作(或仅当另一个操作完成时),您可能需要查看NSOperation(队列)。谢谢,我怀疑我们需要重新考虑该体系结构。我没有为视图编写代码,但我知道我们这样做有特定的原因。不过,解决这些问题可能比解决这个问题更容易。