0

I am having some trouble with dismissing a collection of UIViewController objects. I do not know of an elegant way to dismiss all loaded modal UIViewController objects at once.

I make use of the "storyboard" in Xcode 4, but I do not use Segues to map the screens. I use dynamic code, like so:

It all starts in MainViewController.m. I load [myMenuController] (a menu list). When the user selects an option from the menu, it then loads [myTicketController]. After some user interaction there, it loads [myNextController] and you see the pattern. I load several UIViewControllers dynamically (no segues here):

//from MainViewController.m - Load the main menu
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
myMenuController = (MyMenuController *)[storyboard instantiateViewControllerWithIdentifier:@"MyMenuController"];
myMenuController.settingsModel = settingsModel;
myMenuController.ticketStatusHandler = data;
myMenuController.rootDataModel = dataModel;
[myMenuController setModalPresentationStyle:UIModalPresentationFullScreen];    
[self dismissModalViewControllerAnimated:NO];
[self presentModalViewController:myMenuController animated:YES];


///////////////////////////////////////////////////////////////////////////


//from MyMenuController.m - Load the add ticket menu
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
myTicketController = (MyTicketController *)[storyboard instantiateViewControllerWithIdentifier:@"MyTicketController"];
myTicketController.settingsModel = settingsModel;
myTicketController.ticketStatusHandler = data;
myTicketController.rootDataModel = dataModel;
[myTicketController setModalPresentationStyle:UIModalPresentationFullScreen];    
[self dismissModalViewControllerAnimated:NO];
[self presentModalViewController:myTicketController animated:YES];


///////////////////////////////////////////////////////////////////////////////

//from MyTicketController.m - Load the next screen
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
myNextController = (MyNextController *)[storyboard instantiateViewControllerWithIdentifier:@"MyNextController"];
myNextController.settingsModel = settingsModel;
myNextController.rootDataModel = dataModel;
[myNextController setModalPresentationStyle:UIModalPresentationFullScreen];    
[self dismissModalViewControllerAnimated:NO];
[self presentModalViewController: myNextController animated:YES];

So I get to the end of the app and have loaded several more UIViewControllers. Let's say I load 4 or 5 more UIViewControllers after [myNextController] has been loaded.

Is there a generic way to unload all UIViewControllers that are in memory, and simply reload [myMenuController]?

D3vtr0n
  • 2,630
  • 3
  • 30
  • 48
  • 1
    because i'm not too sure of my answer and since i'm not on my mac, so i'll just comment here. how about placing tags on each controller, and then at a method, check wether that those controller are active or not and then simply dismiss it. – Yonathan Jm Feb 16 '12 at 21:04
  • that sounds cool, like what I'm looking for. But I am not sure how to do that. This is my first iPhone app. – D3vtr0n Feb 16 '12 at 21:05
  • as far as i know, you could use [self.yourView setTag:1] to set the tag and use (UIView *)[self.parentView viewWithTag:1] to point at object with tag:1 inside the parentView. but again, i recommend you try this yourself, and look around a bit – Yonathan Jm Feb 16 '12 at 21:14
  • Do i set the tags when I load the UIViewControllers (like in my examples above), or do the tags set themselves in their class construction? – D3vtr0n Feb 16 '12 at 21:17
  • ah, sorry devtron, seems like i gave you a wrong answer, i don't think you can set tags on UIViewController, the one you can set tag on is UIView – Yonathan Jm Feb 16 '12 at 21:28
  • it would be nice if the storyboard could handle this. i just don't see how. this is very difficult and you'd think this would be simple LOL – D3vtr0n Feb 16 '12 at 21:33
  • i found out a question similar to your problem, maybe you could figure out something from it http://stackoverflow.com/questions/2944191/iphone-dismiss-multiple-viewcontrollers the thing is, its dismissing controllers that are presented from tabBarController, but as long as u're presenting the ViewControllers using modal, this should do the trick – Yonathan Jm Feb 16 '12 at 21:34
  • right but that only works with NavigationController. I am using Xcode 4, and storyboard (with no segues). There seems to be absolutely no easy way to do this. – D3vtr0n Feb 16 '12 at 21:44

2 Answers2

1

well you can define a global array in the app delegate for example and insert the view controllers inside it .. once you want to dismiss all view controllers make a for loop that dismiss all the objects inside it (the view controller ) ,, also you can insert a viewcontroller in specfic index if you want to load it for example

  1. To insert [appDelegate.controllersArr insertObject:self atIndex:0];

  2. To Unload all view Controllers

        for(int i=0;i<[appDelegate.controllersArr count];i++)
    {           
        [[appDelegate.controllersArr objectAtIndex:i] dismissModalViewControllerAnimated:NO];
    }
    

i hope this will be helpful .. good luck.

Malek_Jundi
  • 5,992
  • 2
  • 25
  • 35
  • How would you define the array in the app delegate? What would that syntax look like? – D3vtr0n Feb 17 '12 at 15:28
  • like define any array on any class ! in the interface you declare it make a property ,synthesize .. and because you can access the app delegate on any class you can access the array. – Malek_Jundi Feb 17 '12 at 15:37
  • lets suppose the application delegate class name is AppDelegate .. Import the AppDelegate.h to the class you want to define on it .. then you write `AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;` – Malek_Jundi Feb 17 '12 at 15:49
  • when I try to remove all modal ViewControllers (with your loop), my array is empty. Nothing has been added to the array. Can you explain how to insert better, and the lifecycle of the appDelegate array? How does this work via AppDelegate exactly? – D3vtr0n Feb 17 '12 at 16:29
  • ok .. you will insert the view controller that do you want to keep in the index 0 like my example in the first point above .. when you make the for loop make the initial value of i equal to 1 .. so that will dismiss all the view controllers except the one at index 0 and thats what you want right ? – Malek_Jundi Feb 17 '12 at 20:07
  • the array doesn't seem to be global. once i try to empty (use the loop), the array is nil. How can I persist the array during the entire lifecycle of the application? Your code, step 1 works fine everywhere (from any controller). Step 2 (the loop) doesn't work at all. The array is empty, can you give insight as to why? – D3vtr0n Feb 17 '12 at 22:21
  • Did you retain the array when you declared the property in app delegate ?? – Malek_Jundi Feb 18 '12 at 00:20
1

If you want them to be “unloaded” (I assume you mean deallocated), you simply need to make sure there are no references to them. So you need to dismiss them (which you seem to already be doing), and you need to reset any variables that refer to them, e.g. in MyMenuController you need to do this when you're done with myTicketController:

[myTicketController release]; // if not using ARC
myTicketController = nil;  // if using ARC
rob mayoff
  • 342,380
  • 53
  • 730
  • 766