Forum Xamarin.iOS

How to remove UIViewControllers from stack so ViewDidDisappear is called?

ErnestJErnestJ AUMember ✭✭✭


I've UINavigationController which holds 2 UIViewControllers, second is pushed on the first. I want to replace this navigation controller with a new one, but I need to release existing view controllers from memory first. Currently I remove view with this code:


In this case only top view controller gets its ViewDidDisappear method called, but first controller doesn't and it stays in memory. I've tried calling RemoveFromParentViewController method for both view controllers, but it doesn't call ViewDidDisappear method for any of them!

All this scenario is to do when I'm trying to replace existing detail view controller with a new one. We have a custom built split view controller and when row is selected in master view I create new UINavigationController and set it to DetailViewController of our split view. I don't know how UISplitViewController from SDK handles it, but I imagine it would be the same, e.g when replacing detail view controller with a new one any non top view controllers would never get their ViewDidDisappear methods called.

Any advice is appreciated.

Best Answer


  • adamkempadamkemp USInsider, Developer Group Leader mod

    First, never directly remove a view controller's view from its parent view. That is what the navigation controller does. Let the parent view controller handle that. I'm not sure why you think you need to do this to prevent leaks. You don't.

    Second, the ViewDid/WillAppear/Disappear methods are triggered by the view being added or removed from the window, not just a parent view. When you push a second view controller into the navigation controller the first view controller will have ViewDidDisappear called then. So by the time you are removing the entire navigation controller from the screen the first view controller is already disappeared. There's no work to be done at that point.

    If something is causing a leak then we should take a look at what you're doing in ViewDidDisappear to try to prevent leaks and then figure out why that's not working.

  • ErnestJErnestJ AUMember ✭✭✭

    Thank you adamkemp. I need to remove view controller's view from its parent when I'm assigning new DetailViewController to a split view controller. If I don't do this, current view will not get released. This is how I set new detail view controller in my custom built split view controller:

    ViewControllers[1].View.RemoveFromSuperview(); <--- removes current view
    this.ViewControllers [1] = value; <--- sets new detail controller

    If I wouldn't call 'RemoveFromSuperview' prior to setting new detail controller it would never be released from memory.

  • adamkempadamkemp USInsider, Developer Group Leader mod

    No, you don't. That's not a valid thing to do. We need to find out the real fix for the original problem. Replacing that controller as you do in the second line should automatically cause it to be removed from the view hierarchy.

  • ErnestJErnestJ AUMember ✭✭✭

    So basically you are saying if I've UIViewController with a master and detail views set via UIViewController.ViewControllers property, once I set new detail via ViewControllers[1], old view should be replaced with a new one? For some reason in my case old view stays visible and new one is invisible if the only thing I do is set new controller like this.ViewControllers [1] = value;

    I'll try to create a simple example with UIViewController to replicate the problem I'm having, because our project is huge and impossible to upload here.

Sign In or Register to comment.