iphone connecting code to the 'back' button - iphone

Is there a way to connect code to a view's 'back' button that is part of a navigation controller? That back button is automatically coded in by the nature of it being a navigation controller so I am not sure how I can connect code to it.
(I know this should be really easy but I can't seem to find it in the documentation on navigation controller.)

viewWillDisappear is where you would typically add code to execute when the back button is pressed

In reality you should not have a code that needs to be executed when Back button is pressed. What exactly you're trying to achieve?

You could check if the controller was popped in viewWillDisapper, like in this example:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
NSLog(#"Article done");
}
}

Related

If "setNavigationBarHidden:YES", then how to come back to previous controller?

I don't want to let the navigation controller show its navigation bar in the whole project.
Now there are three view controllers
(1) Login view controller
(2) Sign up view controller
(3) Home view controller.
I just hope to use action(which can be triggered by any kind of event, i.e. drag gesture, not necessary the pressing button) to switch between these view controllers. But I found once I get to the "signup view controllers", I can not go back to the login view controller, since there is no "BACK" navigation bar.
Questions:
How "PUSH" in one view controller, then "POP" in the other view controller?
Or there is some different way to solve this problem?
Thank you so much, any suggestion is great.
To programmaticaly go backward in a navigation controller's navigation stack, call this method:
[self popViewControllerAnimated:YES];
When and where you call this is up to how you want your app to flow. Essentially, the default navigation controller calls this automatically when the navbar's back button is pressed. But if you hide the navbar and still need to pop back, you can call this method to pop back.
As for pushing forward, it's simply a matter of creating a Push segue on the storyboard, giving it a name, and then in your code, call this method:
[self performSegueWithIdentifier:#"segue_YOUR_SEGUE_ID" sender:self];
On the question of your app, what probably makes most sense is for the login view be a view by itself. It should contain a modal segue to a sign up view for new users as well as a modal segue to the home view controller (which may or may not need to be embedded in a navigation controller).
Performing a modal segue works exactly the same as a push segue (if you're using storyboards. Hook up the segue, choose a modal segue, then call the performSegueWithIdentifier: method in your code when you need the segue to occur.
Dismissing a modal view is slightly different, but still quite simple. It goes like this:
[self dismissViewControllerAnimated:YES completion:nil];
It's fairly check to do with an 'if' statement...
if (self.navigationController.navigationBarHidden == NO) {
//YOUR ACTION
}
Hope that helps!

Pushed ViewController is "greyed out" cannot intact with it

Im relatively new to iOS programming and have been making a recipe based app for the iPad. I've looked around at a lot of answers and can't seem to solve my problem so ill explain how my app is laid out.
Navigation controller -> ViewController -Modal segue -> PreviewViewController -modal segue -> Navigation Controller -> RecipeViewController
Within my RecipeViewController i have a button that when pressed i want it to go back to the "home" screen which for these purposes is the "ViewController".
Here is the code for the button action in "RecipeViewController":
- (IBAction)homeB:(id)sender {
ViewController* viewController = [[ViewController alloc]init];
[self.navigationController pushViewController:viewController animated:YES];
}
However, when i press this button the ViewController is displayed, but the screen is greyed out and i can have no interaction with the screen. I can't post an image of what the screen looks like as i don't have enough reputation yet but i will update it when i can.
I have tried other ways of displaying it such as connecting a segue in the storyboard between the button and the "ViewController" and then activating the segue when the button is pressed. But this messes up other parts of my code as i have to re allocate and initialise the home screen. Would appreciate any help as to why it is coming up with the greyed out screen that cannot be interacted with.
Also just some more notes:
self.navigationController
does not return nil so it is seen, and no errors are displayed when the button is pressed.
Thanks
If you're really doing segues, then I presume this was made in a storyboard. If that's the case, then you should use an unwind segue to get back to ViewController. You do this by adding an IBAction in ViewController that looks like this:
-(IBAction)comingBackFromRecipe:(UIStoryboardSegue*)sender {
NSLog(#"I'm back");
}
The important point is that the sender type be UIStoryboardSegue. Then in IB, in the RecipeViewController, you control drag from your button to the green "Exit" icon at the bottom of the controller. When you let go, you should see the method that you wrote in ViewController -- connect it to that. This will get you back to the same instance of ViewController that you started with.
It's hard to tell without seeing a screenshot, but from what i understand, if you want to go back to the home screen, you shouldn't be pushing a new view controller (unless you really want to add it to the stack?)
To go back to the "home" screen, you should try this:
[self.navigationController popToViewController:viewController animated:YES];
or if your home screen is the root, simply use this:
[self.navigationController popToRootViewControllerAnimated:YES];
Thanks for the responses everyone, i figured out my problem though. My structure was wrong and i realised that i didn't need to have another navigation controller for the Recipe view Controller as i wasn't pushing anywhere from there. So incase anyone else has a similar problem my structure is now as follows:
Navigation Controller -> View Controller -Modal Segue -> PreviewViewController - ModalSegue -> RecipeViewController
I removed the Navigation controller between PreviewViewController and RecipeViewController. This means that they are all modal view controllers. So to get back from the RecipeViewController to the home screen which is "ViewController" i just needed to dismiss the hierarchy of modal views with the following code:
UIViewController * parent = self.presentingViewController;
[parent.presentingViewController dismissViewControllerAnimated:YES completion:nil];
I went back two stages so that both the PreviewViewController and the RecipeViewController where dismissed.
Works great now, thanks for the help anyway everyone.

stop view from disappearing

I am launching a viewController from another view controller via the push on its table views cell. Now on the second view controller I have a whole bunch of controls mainly test fields. I would like to by using the default back button provided in the second view controller so it'll be the title of the first view controller and keep in mind like I said default, so I don't want to create my own button for back on the second view controller. So would like to detect if the second view controller is exiting or disappearing or will disappear and based on certain conditions stop it from going back to the original caller view controller. I originally assumed it could be done in here:
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound)
{
// So back button was pressed on the second view controller, so how do I stop it
// here from going back to the original view controller.
}
}
Or how do I do it? I can't seem to find a view controller return type BOOL method to call and stop it.
Thanks.
Note that method is called viewWillDisappear, not viewShouldDisappear, so Apple won't let you stop the view from disappearing at that point. And from the user's point of view, pressing the back button should indeed take them back. Instead you might consider hiding the back button under the circumstances where it's not allowed.
You can't prevent the view controller from closing however you can emulate it.
This line will replace the close button with a button that will call a homemade function
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(closeBtn)];
So you will be able to close the view if you want:
- (void) closeBtn
{
bool shouldClose=true;
// Your conditions here
if (shouldClose) [self dismissViewControllerAnimated:YES completion:nil];
}
sorry,i'm not good at english,so reading so long text is a little difficult for me.i can only get that you want to go back without a button. i known navigationController has a method to go back to previous view.
Make a custom back button and use self.navigationItem.hidesBackButton=YES
Add target to your custom back button and use it as you like. When you want to move the view you can use [self.navigationController popViewcontroller].

black bar as the view fades when I am using navigation controller

I'm writing my first iPhone app and I am trying to figure out how to have a MasterView and DetailsView like in the example. However, instead of using a TableView, I want to use a button on the MasterView to go to the SignUpView. I want the MasterView to NOT have a navigation bar but the SignUpView needs to have one.
I have tried putting a NavigationController into the MasterView using the interface builder. This doesn't seem to do anything at all ... I.e. I make the following call:
[self.navigationController pushViewController:signUpViewController animated:YES];
And nothing happens. The SignUpView is never shown.
So then I declared a NavigationController in the AppDelegate. The above call in the same function that it was in before (button handler, button is in MasterView) works now! It takes me to the SignUpViewController.
however, the issue is, when I press back on the navigation bar in the sign up view, the navigation bar shows up again in the MasterView. I tried to set
self.navigationController.navigationBarHidden = YES;
in viewDidLoad and viewDidAppear, but that causes a black bar to appear in the transition from SignUpView to MasterView.
I tried to not set it in one of the two, and that causes the animation to go smoothly, but the navigation bar shows up in the MasterView.
I feel like this should be pretty simple to do ... but I'm at my wits end trying to figure this out. Some help would be really appreciated!
Thanks.
Probably not the answer to your question, but just a small suggestion. In the many apps that I have come across, a sign-up/sign-in view is generally displayed as a modal view (on top of your master view) with a 'cross' in the top-right corner to dismiss it. Probably it results in a better user experience.
Also, did you try self.navigationController.navigationBarHidden = YES; in the MasterView's viewWillAppear ?
HTH,
Akshay
I had this problem too, until I discovered setNavigationBarHidden. You will probably want to use these in viewWillAppear/viewWillDisappear or viewDidAppear/viewDidDisappear. You don't want to call this in viewDidLoad because that is only called once when the view is initialized, not every time it appears.
To hide:
[self.navigationController setNavigationBarHidden:YES animated:YES];
To show:
[self.navigationController setNavigationBarHidden:NO animated:YES];

Custom behavior when "back" button in nav bar pressed

I know that you can add a custom "back" button to a UINavigationBar, but doing so removes the existing button with the tapered left side, as described in What happens when back button is pressed in navigationBar
Is there any way to keep the existing behavior and look of the back button, but also be informed when it is pressed?
Basically, I want my app to play a sound whenever any button is touched. I can do it with UITabBarController via its delegate, but the delegate for UINavgationBarController has no such functionality.
The following are the possibilities for a View Controller to disappear.
Clicking on a button (other than backBarButtonItem).
Clicking on the backBarButtonItem
Either case viewWillDisappear: method will be called. Keep a boolean flag. Lets name it isAnyButtonClicked. And set isAnyButtonClicked = YES whenever any button is clicked. And override the viewWillDisappear: method, and play the sound if no button is clicked(ie., isAnyButtonClicked == NO). Probably your viewWillDisappear: would look like,
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (!isAnyButtonClicked) {
// Play sound
isAnyButtonClicked = NO;
}
}