mike vorisis
mike vorisis

Reputation: 2832

How to move through Views without reload them again if I return back Swift

I'll give an example of what I want so it's not so confusing:

Example:

Let's say that I have a map that adds every time that my user scrolls 3 annotations dynamically. Now I have a button under the map and when I press it I go to another viewController do what I want and get back to the viewController with the map, now I want to find all the annotations that my map had and not reload the view at all.

I used to use this function that I made to move between viewControllers:

func move(identifier: String , viewController : UIViewController) -> Void {
    let mstoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let vc: UIViewController = mstoryboard.instantiateViewControllerWithIdentifier(identifier) 
    viewController.presentViewController(vc, animated: true, completion: nil)
}

I also tried this:

let vc = self.storyboard?.instantiateViewControllerWithIdentifier("view") as? MyViewcontroller
         self.presentViewController(vc!, animated: true, completion: nil)

These two when I use them the viewcontroller that appears is calling viewDidload so its like it appeared for the first time.

Another example is the tabBarViewController if you notice when you navigate through tabs nothing reloads (only function that is called is viewDidAppear )

EDIT

test file

Upvotes: 2

Views: 2245

Answers (2)

Rikh
Rikh

Reputation: 4222

According to the same project you posted, you instantiate a new UIViewController when going from view 2 back to view 1 and that is why your viewDidLoad gets called again and your entire map view is reloaded.

In your sample project, instead of

lazy var mapController2 = { () -> UIViewController in
    let mstoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    return mstoryboard.instantiateViewController(withIdentifier: "first")
}

You should just dismiss your view 2 on the button press.

@IBAction func butto(_ sender: AnyObject) {
      //Your initial code
      //PresentingController().moveToMap(self, flag: 1)

      self.dismiss(animated: true, completion: nil)
}

When you present a new UIViewController, the older UIViewController is not removed from memory, it is just hidden behind the new UIViewController. So whenever you wish to go back to a UIViewController with the previous state maintained, all you need to do is close the new UIViewController

However, if you are doing some tasks that you performed on your second UIViewController that you wish to be reflected in your initial UIViewController, you will have to setup closures to update your initial UIViewController.

Upvotes: 1

Cristik
Cristik

Reputation: 32853

The problem is caused by the fact that the map controller gets deallocated when navigating back to the other controller, and another one is created when you want to move again to the map screen.

What you need is to hold on onto the same controller instance, and present that one. Keeping a strong reference in the presenting controller would suffice.

class PresentingController {
    // making the property lazy will result in the getter code
    // being executed only when asked the first time
    lazy var mapController = { () -> UIViewController in
        let mstoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        return mstoryboard.instantiateViewControllerWithIdentifier("mapControllerIdentifier")
    }()

    func moveToMap() {
        // simply use the mapController property
        // the property reference will make sure the controller won't
        // get deallocated, so every time you navigate to that screen
        // you'll get the same controller
        presentViewController(mapController, animated: true, completion: nil)
    }
}

Upvotes: 2

Related Questions