How to create a slide-out menu (like on the Facebook app) without the home screen reloading? (ios)

624 Views Asked by At

So I've been using this tutorial to implement a sliding menu on my iOS app. However, when I try to hit the home cell button, the home controller refreshes as it, from my understanding, is placing another version of the controller on top of the old one. I'm building a game so you can see why this situation is not ideal--essentially, it is creating a new game each time the user uses the slide out menu. Is there anyway to prevent this refresh from happening or an alternate possible workaround?

1

There are 1 best solutions below

11
Michael Lorenzo On

Based off what the tutorial is telling you, a segue is performed for each cell item in the menu. What you should do to prevent reloading of an already present View controller is perform the segue in didSelectRowAtIndexPath:, except do a check to see if the current view controller is equal to the one you selected. You should make all of the possible view controllers properties of the menu controller and have the menu controller be the root controller. This way you can detect if the last view controller was the selected one. On the controller that manages the menu in the delegate method didSelectRowAtIndexPath:, add this:

In menuController.h

@property (retain, nonatomic) OneViewController *thatViewController;

In menuController.m's didSelectRowForIndexPath:

NSArray *segueIdentifiers = @[@"firstSegueID",@"secondSegueID",...];//list of all segues possible in order matching the rows, so row0 would associate to the firstSegueID
if ([segueIdentifiers objectAtIndex:indexPath.row] isEqualToString:@"firstSegueID"])
{
    BOOL isInstantiated;
    isInstantiated = NO;
    if (self.thatViewController == nil) //or some way to check if it was already instantiated like testing a property of the controller
    {
        self.thatViewController = [[OneViewController alloc] init]; //or whatever init class method you like
        [self.thatViewController.property setThemHere];

        isInstantiated = YES;
    }

    [self presentViewController:self.thatViewController animated:YES completion:^{NSLog(@"presented that view controller, was reloaded: %@",isInstantiated);}];
}

EDIT1: So basically, instantiate the controller once:

Then place your object instantiations in proper locations in the oneViewController.m. For instance, objects you do not want to be volatile (which I am assuming is everything on the home controller) should be allocated and initialized here. This will require you to move over most of your UI mechanics to programming and away from story board. I believe when you perform a segue, it will allocate and create a new view controller and then run performSegueWithIdentifier:animated:.

EDIT2: I just realized I mistyped my code, they should now contain the latest revision, I apologize for the confusion.

EDIT3: If you still want to retain the way the method slides over, I am not too particular on animated presenting and dismissing view controllers. However, the same logic can be applied by just instantiating it strictly by doing the method from this post. If you dont want to bother:

if (! self.thatViewController) {
    self.thatViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"HomeViewController"]; // set this property in the story board
}

Then you can perform the segue without it allocating a whole new controller.