I'm using a UINavigationController to navigate between classes. When I press a button on the first view to send me to the second one, everythin works fine. But when I wan't to return from the second, to the first view, the viewDidLoad method isn't being called, and I really need that to happen.
According to this post, I should somehow set my view to nil but I'm not sure where or how to do that. This is the code that I'm using to return to the first view:
NewSongController *nsContr = [[NewSongController alloc] initWithNibName:#"mNSController" bundle:nil];
[self.navigationController popViewControllerAnimated:YES];
[nsContr release];
Your code is not correct.
You don't need to instantiate your first controller in order to pop to it. It already exists.
viewDidLoad will only run when you load the viewController for the first time (i.e. when you push to it). When you push to other controllers they are put onto a stack (imagine a stack of cards). When you push another card onto the stack the cards beneath it are already there.
When you pop it is like removing a card from the stack. But the card underneath is already there so it doesn't need to load again. All it does is run viewWillAppear.
All you need to do to pop back is...
[self.navigationController popViewControllerAnimated:YES];
That's it.
Remove the stuff about NewSongController (if that is what you are trying to go back to).
Then in the NewSongController function - (void)viewWillAppear:animated; put the code you want to run when you get back to it.
Hope that helps.
Your first view is loaded and is pushed onto the navigation stack. Dont try to mess with whats on the stack without fully understanding how setting the view to nil will affect the behavior.
Whatever you do on viewDidLoad, doing it in viewWillAppear or viewDidAppear will give you the result you want.
The viewDidLoad wouldn't appear because it already exists in the navigation stack. Since you are going back in the stack you would want to have the code that you want to trigger in viewWillAppear or viewDidAppear which is executed when popping from one viewcontroller to the one below it.
Related
I am several levels deep in a storyboard and want to unroll everything all the way back to the first screen. Fortunately, there are APIs designed to do exactly this:
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
[topController dismissViewControllerAnimated:NO completion:nil];
However, this method seems to "unroll" the view stack one by one, causing each view between my current position and the first screen to briefly invoke viewWillAppear, viewDidAppear, viewWillDisappear, and viewDidDisappear. This causes a cacophony of activity in my app, as most of the intermediate screens do interesting things when they appear. I can set breakpoints in Xcode and watch these methods get invoked in reverse order back to the main screen.
I need a way to pop back to the start of the storyboard without causing every screen along the path to light up and do work.
If this means I cannot use viewWillAppear for this purpose any more, I am willing to switch to a replacement method as long as one exists.
This is expected behaviour. I assume you're presenting the layers of views with presentViewController... calls on each previous view.
You should look at using a UINavigationController as your top level view instead. Then you can just call popToRootViewControllerAnimated: when you want to go all the way back.
I am using storyboard and i stumbled upon something i have not been able to grasp.
I am putting up my view controller programmatically with performSegueWithIdentifier:.
It works like a charm, but what i noticed was that every single time i do this, i create a new instance of that viewController, and so, i have memory that keeps piling up. When i simulate a memory warning, i see that for each time i have been calling performSegueWithIdentifier:
i have a new instance of the view controller, and it NEVER gets deallocated. So memory just piles up and i cannot release it, which eventually causes a crash.
I just go to the view controller like this:
// If sales are registered, go to view
[self performSegueWithIdentifier:#"previousSaleSegue" sender:self];
What am i missing here?
You'll be stacking view controllers on top of each other instead of returning to a previous one. Assuming you are using a navigation controller, you'll be doing this:
A --push--> B --finished! Push---> New A ---Push---> B ---Finished! push--->A ...
What you should be doing is:
A --push--> B --finished! Pop -
^-----------------------------/
You're using modal segues by your comments, in this case you need to add an action to your return button to dismiss the view controller (returning to the previous one) instead of presenting another instance. The principle is the same. You'd use
[self dismissViewControllerAnimated:YES completion:nil];
If you're certain that viewcontroller instance does not get deallocated it must be because you keep reference to it somewhere (it could be a cycle on the controller itself).
I have an app I am working on that has a main screen with two buttons. One will take you to a view of a GPS (map) and then once there (new VC) it has options for setting that position or bringing up a list (tableview, another VC) of all locations already tagged.
At the list VC, if you click on the table cell, it will bring up the VC with the map. Problem is, this then adds the same VC bak on the stack. If a user clicks the Cancel button, they go back ones screen, then cancel goes back another screen, etc... until back to the main.
I know I can do the [self.navigationController popToRootViewControllerAnimated:YES]; to pop back to root but that is not always what I want.
Also, I know I can do: [[[self presentingViewController] presentingViewController] dismissModalViewControllerAnimated:YES];
I guess what I am saying is I want to "reuse" the GPS map view so I can call it from other VC's, so that is why I didn't go with the "pass back" to calling VC. So, is there away to either when a button is pressed and is to present a new VC, can I dismiss the prior one after the new one is shown? This way, a dismiss of current VC would take me back to where I need to be.
I hope makes sense and also that this question doesn't fall into the "Not an actual question" category.
Any help or better suggestions is greatly appreciated. Thx
Geo...
If you want to jump back some number of levels in a navigation controller's VC stack, you'll probably want to use its popToViewController:animated: method. To figure out if a particular view controller is on that stack, look at the navigation controller's viewControllers property. Be careful, though, as this kind of jumping around is a rather nonstandard UI behavior (even though there's API for it) which might confuse your users.
Also, using navigation controllers and presenting modally aren't the only ways to manage multiple view controllers -- you can always set the window's rootViewController yourself (and animate the change with UIView animations), even wrapping up your custom transition type in a custom UIStoryboardSegue if you like.
You can put a delegate in the table view. So that when a cell is pressed the info is passed to the delegate method in the VC which will dismiss the table view and reloads itself with the new info. You will have to implement refresh method in that VC.
I have created a tabBarNavigated Application. In second tab, I do something that works fine, but now I want to do something in the first Tab, so first I try to NSLog a string, but I get no reaction.
- (void)viewDidLoad
{
NSLog(#"Test");
}
If I add a label to the view, it will be displayed, but no reaction on my code.
if I start my app, i see this view, but i can't call any actions in this method, even if i change the tab, and go back to the first one, still no logs.
I try to NSlog in GehaltView
this is the mainWindow
viewWillAppear dosn't work :(
The -viewDidLoad method is only called when your view is loaded. This method will not be called again unless the view gets unloaded, in which case -viewDidUnload will be called. A view can be unloaded if there is a memory issue, but otherwise they generally stick around.
If you want to trigger an action that happens every time the view appears, then you can use the -viewWillAppear: method instead. This method is called every time the view re-appears. You can track when the view disappears with -viewWillDisappear, and watch the two get called as you toggle between the two tabs.
Note also that -viewDidLoad may get called before the view appears, but -viewWillAppear will only be called when the view actually appears (or moments before, as the will indicates).
EDIT: The code should read
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(#"View Will Appear");
}
EDIT: This entire answer assumes that you have a subclass of UIViewController. It seems to me that you are by-passing using viewControllers, which in general is a bad idea.
I found the solution, in interface builder i have to add a custom class to the forst tab.
I'm writing a program with a UITableView with and add button in the Navigation Bar which leads to an edit page. When you click on an item in the table, a view (rView) is pushed with information pertaining to that item. This view has an edit button that also leads to the edit page. Is there a way that I could put an if statement for the done button on the edit page that says "if parentViewController is the UITableView to go to rView, else popViewController?" I would assume there is a way to do this, but I'm not sure of the syntax to do so. Thanks
If I understand correctly you have a UINavigationController and push onto it
a UITableView
an "rViewController" (you can't push a view, must be a controller)
an "EditController"
But there is a possibility that step 2 is omitted and you go directly to the edit screen.
Now when the last controller is popped, you want to be able to always go to a "rViewController", even if it's not on the stack.
First of all, the parentViewController is NOT the previous controller on the stack, but rather the UINavigationController itself, so it has nothing to do with the present problem.
The way to do this is by setting the UINavigationController's viewControllers property explicitly with an NSArray. I haven't tried this but this should work:
When a user presses the "add" button, instead of just pushing the edit view controller, do something like:
NSArray* stack = navigationController.viewControllers;
navigationController.viewControllers = [stack arrayByAddingObject:rViewController];
[navigationController pushViewController:editController animated:YES];
(By the way, I would suggest not using names like "rView" except maybe for very short-lived local variables, like in a loop. Using descriptive names is very much part of the Cocoa idiom and will help you a lot in the long run.)