3
votes

When I add child view controller to table view cell, it looks like viewWillAppear for child view controller is not called, only viewDidAppear.

Table View Controller method:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell = tableView.dequeueReusableCellWithIdentifier("ShopInfoTableViewCell", forIndexPath: indexPath) as! ShopInfoTableViewCell
    self.addChildViewController(self.shopInfoViewController, toView: cell.containerView)
    return cell
}

View Controller category method:

- (void)addChildViewController:(UIViewController *)childController toView:(UIView *)view
{
    [self addChildViewController:childController];
    [view addSubview:childController.view];
    [childController didMoveToParentViewController:self];

    [childController.view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(view.mas_top);
        make.bottom.equalTo(view.mas_bottom);
        make.left.equalTo(view.mas_left);
        make.right.equalTo(view.mas_right);
    }];
}

Any ideas why it happen?

2

2 Answers

26
votes
- (void)addChildViewController:(UIViewController *)childController toView:(UIView *)view
{
    [self addChildViewController:childController];

    //add this
    [childController beginAppearanceTransition:YES animated:YES];
    [view addSubview:childController.view];
    [childController endAppearanceTransition];

    [childController didMoveToParentViewController:self];

    [childController.view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(view.mas_top);
        make.bottom.equalTo(view.mas_bottom);
        make.left.equalTo(view.mas_left);
        make.right.equalTo(view.mas_right);
    }];
}

Likewise, you should call this when you want to disappear

    [childController beginAppearanceTransition:NO animated:YES];
    [childController.view removeFromSuperview];
    [childController endAppearanceTransition];
-1
votes

To @adali answer I would change:

[childController beginAppearanceTransition:YES animated:YES];

by:

[childController willMoveToParentViewController:self];

So at the end it would be:

[self addChildViewController:childController]; //add the child on childViewControllers array
[childController willMoveToParentViewController:self]; //viewWillAppear on childViewController
[self.containerView addSubview:childController.view]; //add childView whenever you want
[childController didMoveToParentViewController:self]; //viewDidAppear on childViewController

And very important, all this must be called once the viewController that contains the children has already executed its viewWillAppear life cicle function