简体   繁体   中英

How do I propagate subview resizing to superview resizing?

I'm trying to do the opposite of what the autoresizing mask automatically does. That is, I have a view hierarchy and I need to propagate a change in the deepest subview frame all the way up the chain, so that all the subviews resize to fit the newer (possibly bigger) subviews.

Specifically, I have a scroll view that has aa subview as a container, which contains a table, and another view which in turn contains an image and another table. Like so:

在此输入图像描述

And this is the chain of events:

A)

1 The innermost table, of 2 rows, might have to stretch down if the name of the person is too long (meaning the cell heights are variable and calculated at runtime on heightForCellAtIndexPath).

2 If so, this needs to trigger the stretching of the container view for this table and the image, so that no cells of the table end up overflowing the view.

3 And if that's the case, then the other table below this container view needs to translate down a bit to make sure it's not overlapping. Note that the chain could also start here, even if steps 1,2 don't take place. This would be the case if any this table's 3 rows happens to stretch to accommodate longer text.

4 If any of the above result in an increase in length, the outermost container view needs to stretch in length too.

5 Finally, if this outer container view did stretch, the root scrollview needs to change its contentSize property so that the new bigger view fits and can be fully scrolled if bigger than the device's screen.

The first problem is knowing when (at what point in code) is the innermost table done laying out its cells and its final frame computed. If I knew when is the final frame known, I could send a KVO notification on view.frame change to the single view controller managing all these views. But then the controller would have to manually resize all the subviews frames. I've tried this approach but the frames don't seem accurate. I'm wondering if there might be timing issues I'm not considering.

This works for instance:

- (void)viewDidLoad
{
  ...

  [self addObserver:self forKeyPath:@"attendeeContentView.frame" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{
  if([keyPath isEqualToString:@"attendeeContentView.frame"]) 
  {
    CGRect newFrame = [[change objectForKey:NSKeyValueChangeOldKey] CGRectValue];
    UIScrollView *scrollView = (UIScrollView*)self.view;
    scrollView.contentSize = CGSizeMake([[UIScreen mainScreen] applicationFrame].size.width, newFrame.size.height + newFrame.origin.y);
    NSLog(@"\n new contentSize: %f", newFrame.size.height + newFrame.origin.y);
  }
}

But this is only the final link in the chain. It all starts with the innermost table expanding to fit all cells...

Any ideas?

You can just check for the last call of - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

if (indexPath.row == (NumberOfCells - 1)) {
        // update your views (preferably call it after a slight delay)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM