Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Remove a Previous ViewController

I am a student and pretty new to programming. I am trying to learn Objective-C/Swift in my spare time. I made a game using spriteKit with swift that has multiple menus/scenes.

I am trying to transition from one view controller to another. To do this I used this code:

@IBAction func PlayButtonPressed(sender: AnyObject) {
    let playStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let vc : UIViewController = playStoryboard.instantiateViewControllerWithIdentifier("playGame") as UIViewController
    self.presentViewController(vc, animated: true, completion: nil)
}

This works for transitioning to the new VC scene, however, I believe the previous VC is still in the stack and takes up memory, slowing down my program.

I've read on some other posts that you can use the navigation controller to remove VC. However, I do not have a navigation controller; only view controllers. I've seen some stuff about removeFromParentViewController() and view.removeFromSuperview(), but I don't really know how to implement it. Other than that I did not find an answer that I was looking for.

So the question I am asking is how do I remove the previous VC from the stack? Any help would be a appreciated! (would prefer the help to be in swift, but Objective-C would help also) Thank you in advance!

note for reference: I believe in Objective-C my code would look something like this:

-(IBAction) PlayButtonPressed: (id) sender {
    UIStoryboard *playStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UIViewController *vc = [playStoryboard instantiateViewControllerWithIdentifier:@"playGame"];
    [self presentViewController:vc animated:YES completion:nil];
}
like image 583
Kirby Avatar asked Aug 03 '14 21:08

Kirby


People also ask

How do I delete a navigation stack controller?

Use this code and enjoy: NSMutableArray *navigationArray = [[NSMutableArray alloc] initWithArray: self. navigationController. viewControllers]; // [navigationArray removeAllObjects]; // This is just for remove all view controller from navigation stack.

What is the difference between View and ViewController?

A view controller is not drawable to the screen directly, it manages a group of view objects. View controllers usually have a single view with many subviews. The view controller manages the state of these views. A view controller is smart, and has knowledge of your application's inner workings.


2 Answers

I guess best implementation is to place the following at the previous View Controller - Swift

    // Override to remove this view from the navigation stack
    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
        // Remove self from navigation hierarchy
        guard let viewControllers = navigationController?.viewControllers,
            let index = viewControllers.indexOf(self) else { return }
        navigationController?.viewControllers.removeAtIndex(index)
    }
like image 139
Mazen Kasser Avatar answered Sep 17 '22 11:09

Mazen Kasser


As I can assume, view controller being presented on the screen was instantiated either automatically from main storyboard or by setting app's window.rootViewController property.

In either case you can set rootViewController again to be your vc. To change rootViewController of your app you need to replace this line of code:

self.presentViewController(vc, animated: true, completion: nil)

... with one of the options bellow.

"Navigate" without transition animation:

Objective-C

UIWindow *window = (UIWindow *)[[UIApplication sharedApplication].windows firstObject];
window.rootViewController = vc;

Swift

let window = UIApplication.sharedApplication().windows[0] as UIWindow;
window.rootViewController = vc;

"Navigate" with transition animation:

Objective-C

UIWindow *window = (UIWindow *)[[UIApplication sharedApplication].windows firstObject];
[UIView transitionFromView:window.rootViewController.view
                    toView:vc.view
                  duration:0.65f
                   options:UIViewAnimationOptionTransitionCrossDissolve // transition animation
                completion:^(BOOL finished){
                    window.rootViewController = vc;
                }];

Swift

let window = UIApplication.sharedApplication().windows[0] as UIWindow;
UIView.transitionFromView(
    window.rootViewController.view,
    toView: vc.view,
    duration: 0.65,
    options: .TransitionCrossDissolve,
    completion: {
        finished in window.rootViewController = vc
    })

Remarks: Once rootViewController value gets changed your original view controller reference count should became 0 hence it will be removed from the memory!

like image 29
Keenle Avatar answered Sep 20 '22 11:09

Keenle