Load a view that is previously loaded in iOS - ios

I have been searching around about this problem, but haven't got any answer yet. My problem is: I have a push button that when clicked will push to another view.
Here is how I push it:
ViewController *vc = [[UIStoryboard storyboardWithName:#"Main" bundle:nil]
instantiateViewControllerWithIdentifier:#"Main_View"];
[self.navigationController pushViewController:vc animated:YES];
The ViewController vc is the view that I pushed. So in the new view, there is a Back button that can drop the current view and comeback to the old view. When I click the push button, the vc been load again from allover.
How can I make the instance of vc stay in memory, so when I go back to old view and come to vc again, it doesn't need to reload again?
I guess it is something related to navigationController stack, but don't know how to do that.
Thanks

Just keep a ViewController instance as property in your first ViewController
#property (strong,nonatomic)ViewController * vc;
Then when push it,check if it is in memory
if (self.vc == nil) {
self.vc = [[UIStoryboard storyboardWithName:#"Main" bundle:nil]
instantiateViewControllerWithIdentifier:#"Main_View"];
}
[self.navigationController pushViewController:self.vc animated:YES];

Are you using a UINavigationController? If so, can call the following line of code in you back button 'IBAction':
[self.navigationController popViewControllerAnimated:YES];
If you really need to keep a instance of the view controller, do what Leo suggested.

Related

Navigation between Controllers - Black Screens

I'm trying to work on a simple login application which on successful login displays a menu page. On the action sheet of menu page, we have an option of looking at all the users logged in that phone and clicking on any user, it should do some login processing and direct to menu page again. This is how the workflow should go on.
Below is the image that explains it.
All the controllers are connected to segues except for accounts controller and middle controller. Navigation between those two is done using pushViewController as I had to pass some info from accounts controller(table view controller with list of all users) to middle Controller.
MiddleController *maController = [[MiddleController alloc] init];
if (maController.view) {
maController.ma_userId = mo_userId; // Set the exposed property
maController.ma_password = mo_password;
[self.navigationController pushViewController:maController animated:YES];
Middle controller is doing all the process perfectly after getting the details. But directing to menu controller is where I'm facing the problem. If I use a segue between middle controller and menu controller an error is thrown saying no identifier with the name segueName found. But if I use a pushViewController then it is displaying a blank black screen. Can some help me to solve this.
This is how I'm pushing it:
MenuTableViewController *mapMenuTableviewController = [[MenuTableViewController alloc]init];
[self.navigationController pushViewController:mapMenuTableviewController animated:NO];
I've tried all the ways that are posted in previous SO questions, but nothing helped.
Thanks in advance
Try not to alloc-init, but instantiate it fom storyboard like this (you should add it a storyboard id)
YourViewControllerClass *viewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"ViewController"];
And then push it.
You need to add storyboard id like this
And use like
UIViewController *viewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"ViewControllerID"];
Go to your storyboard, and set an identifier like this :
Now, in your view controller, do this :
YourViewController *viewController = [[UIStoryboard storyboardWithName:#"<your storyboard name>" bundle:nil] instantiateViewControllerWithIdentifier:#"myViewControllerID"];
[self.navigationController pushViewController:viewController animated:NO];
UPDATE -
Push you Accounts view controller and Middle view controller the way i told before.
Then, when your processing is done in the middle controller, just do this :
[[self presentingViewController]presentingViewController]dismissViewControllerAnimated:NO completion:nil];
Add storyboard Id to yput interface builder "SendSMSViewController" and call below code.
let SendSmsVC = self.storyboard?.instantiateViewControllerWithIdentifier("SendSMSViewController") as! SendSMSViewController
self.navigationController?.pushViewController(SendSmsVC, animated: true)
Plz use this code you will go to MenuTableViewController.
for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[MenuTableViewController class]])
{
[self.navigationController popToViewController:controller animated:YES];
break;
}
}

How can I remove from memory the view controller I am exiting after I press a button?

Upon pressing a button in ViewController A, I want that view controller to completely be forgotten as I move to ViewController B. Here is my code to get to code B:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
MapViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"MapView"];
[self presentViewController:vc animated:NO completion:nil];
Is there any way to stop the view controller that calls presentViewController from staying in memory? How can I dismiss it upon exit?
One Possible way to do it, is you have the following Setup.
Navigation Controller -> VC_A -> VC_B.
Here when you click on the button in VC_A, you ask the Navigation controller can remove VC_A from the navigation Stack & create and VC_B as the root view controller on the navigation stack and present it.
I still think this is not the right approach. If you could explain why you want to get rid of VCA, we might be able to think of a better solution.
dont remove from memory you can update its contents in viewWillAppear or viewDidAppear

Push ViewController in NavigationController from side menu

I'm using a UINavigationController and I have a side menu in it. The problem is that when I want to push a UIViewController in the NavigationController from the side view it doesn't work. To do it, is use that code:
[self.slidingViewController resetTopView];
CDRecentChats* recentchats = [[CDRecentChats alloc]init];
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"conversation"];
[recentchats.navigationController pushViewController:controller animated:YES];
As you can see, I first close de side menu and then call the NavigationController to push a new ViewController. Using that code, the only thing that happens is that the menu is closed, but the NavigationController doesnnt push any ViewController. what can I do?
popToViewController means to go back to one that has already been made part of the navigation controller's stack. If you're trying to show a new one, use pushViewController.

Switching views without initialization in iOS

There are two views in my application.
After launching the app I switch the view with button like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:[NSBundle mainBundle]];
UIViewController *view = [storyboard instantiateViewControllerWithIdentifier:#"view_a"];
[self presentViewController:view_a animated:NO completion:nil];
But whenever i switch the view the code above initialize the view.
I want to maintain previous status of the view.
How can I solve this problem?
instantiateViewControllerWithIdentifier: always returns a new instance of an UIViewController.
You need to keep a reference to a previous one if you don't want to create it over and over.
On an iPad this will present the second view modally, as dictated by the views modalTransitionStyle. So there you could get back to the original by calling dismissViewControllerAnimated:completion: on the new ViewController.
On the iPhone you can use a UINavigationController in your storyboard to push and then pop the secondViewController.
As long as you are using the storyboard, you can set up the transition there and the perform it using - performSegueWithIdentifier:sender: from your button. Or for that matter you can connect the segue directly to your button in which case the transition will be performed without additional code.

Storyboard UITabBaar, initiate two different views from button

I've created a storyboard that has a UITabbarController all is working well but now I want to add some logic that determines which viewcontroller a particular tabbar button will display.
Example... if a customer has a valid subscription display viewcontroller one, if no subscription display viewcontroller two.
Is this possible using storyboards, I've looked at UITabBarDelegate and prepareForSegue but struggling to piece this together?
Are there any examples of how to do this sort of thing using StoryBoards?
Many thanks
You can set it like this:
if(hasSubscription)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
ViewController1* subsection = [storyboard instantiateViewControllerWithIdentifier:#"ViewController1"];
ViewController2* subsection1 = [storyboard instantiateViewControllerWithIdentifier:#"ViewController2"];
[(UITabBarController*)self.window.rootViewController setViewControllers:[NSArray arrayWithObjects:subsection,subsection1, nil]];
}
If you want to add rootviewController according to the subscription then above answer given by soryngod is good one.
But if you want to open viewControllers after rootviewcontroller loaded, then at tabBarButton press perform following code:-
before this code, add yours viewControllerONE and viewControllerTWO to the rootViewController by segues as shown: . And give each segue an identifier in AttributeInspector, example "one" for viewControllerONE and "two" for viewControllerTWO.
then at tabBarButton action do the following:-
if(subscription)
[self performSegueWithIdentifier:#"one" sender:self];
else
[self performSegueWithIdentifier:#"two" sender:self];

Resources