xonegirlz
xonegirlz

Reputation: 8967

viewDidAppear not getting called

In my main UIViewController I am adding a homescreen view controller as subviews:

   UINavigationController *controller = [[UINavigationController alloc] initWithRootViewController:vc];
        controller.navigationBarHidden = YES;
        controller.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
        [self addChildViewController:controller];
        [self.view insertSubview:controller.view atIndex:0];
        [controller didMoveToParentViewController:self];    

The issue is that viewDidAppear and viewWillAppear is only called once, just like viewDidLoad. Why is this? How do I make this work?

Basically inside vc I am not getting viewDidAppear nor viewWillAppear.

I also just tried adding the UIViewController without the navigation controller and it still doesn't work:

vc.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
        [self addChildViewController:vc];
        [self.view insertSubview:vc.view atIndex:0];
        [vc didMoveToParentViewController:self];    

Upvotes: 10

Views: 31331

Answers (9)

Coder ACJHP
Coder ACJHP

Reputation: 2194

Here is another case when presenting viewController programmatically;

viewWillAppear or viewDidAppear not being called when presenting viewController with modalPresentationStyle .overCurrentContext, use .currentContext both functions will be triggered

let destinationVC = TestAppearanceViewController()
destinationVC.modalTransitionStyle = .coverVertical
destinationVC.modalPresentationStyle = .currentContext // Remove behind view controller and force presenter view controller calls both functions
vc.present(destinationVC, animated: true)

Upvotes: 0

user2905353
user2905353

Reputation: 376

Another case where this will not be called at launch time (yet may be called on when you return to the view) will be is if you have subclassed UINavigationController and your subclass overrides

-(void)viewDidAppear:(BOOL)animated

but fails to call [super viewDidAppear:animated];

Upvotes: 3

RichApple
RichApple

Reputation: 3

When updating my code to 13.0, I lost my viewDidAppear calls.

In Objective-c, my solution was to add the following override all to the parent master view controller.

This allowed the ViewDidAppear call to get called once again...as it did in previous IOS (12 and earlier) version.

@implementation MasterViewController

//....some methods

  • (BOOL) shouldAutomaticallyForwardAppearanceMethods { return YES; }

// ...some methods

@end

Upvotes: 1

Ivan Cantarino
Ivan Cantarino

Reputation: 3246

@Rob answer in Swift 4 (which helped me on my case which I was adding a childViewController to a UITabBarController)

override var shouldAutomaticallyForwardAppearanceMethods: Bool {
    return true
}

Upvotes: 12

luky
luky

Reputation: 2370

In my case, viewDidAppear was not called, because i have made unwanted mistake in viewWillAppear method.

-(void)viewWillAppear:(BOOL)animated {
    [super viewdidAppear:animated]; // this prevented my viewDidAppear method to be called
}

Upvotes: 35

Tim
Tim

Reputation: 1894

Had a same problem My container view controller did retain a child view controller via a property, but did not add a child view controller to its childViewControllers array.

My solution was to add this line of code in the container view controller

[self addChildViewController: childViewController];

After that UIKit started forwarding appearance methods to my child view controller just as expected

I also changed the property attribute from strong to weak just for beauty

Upvotes: 1

Marián Černý
Marián Černý

Reputation: 15748

My problem was that I was changing the tab in UITabBarController (selectedIndex = x) and then messing with the child view controllers in that tab. The problem is that it needs to be done the other way round: first mess with the child view controllers in other tab and then change the tab by setting the selectedIndex. After this change methods viewWillAppear/viewDidAppear begun to be called correctly.

Upvotes: 0

Rob
Rob

Reputation: 437552

The only way I can reproduce the problem of child controllers not receiving appearance methods is if the container view controller does the following (which I'm sure you're not doing):

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
    return NO;
}

Perhaps you can try explicitly enabling this:

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
    return YES;
}

But my child view controllers definitely are getting the viewWillAppear calls (either if I explicitly automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers or if I omit this altogether.

Update:

Ok, looking at the comments under your original question, it appears that the issue is that the child controller (B) in question is, itself, a container view controller (which is perfectly acceptable) presenting another child controller (C). And this controller B's own child controller C is being removed and you're wondering why you're not getting viewWillAppear or viewDidAppear for the container controller B. Container controllers do not get these appearance methods when their children are removed (or, more accurately, since containers should remove children, not children removing themselves, when the container removes a child, it does not receive the appearance methods).

If I've misunderstood the situation, let me know.

Upvotes: 15

Alex Gosselin
Alex Gosselin

Reputation: 2930

Presenting view controllers using presentModalViewController or segues or pushViewController should fix it.

Alternatively, if for some reason you want to present your views without the built-in methods, in your own code you should be calling these methods manually. Something like this:

[self addChildViewController:controller];
BOOL animated = NO;
[controller viewWillAppear:animated];
[self.view insertSubview:controller.view atIndex:0];
[controller viewDidAppear:animated];
[controller didMoveToParentViewController:self];   

Upvotes: -10

Related Questions