Segue to home view - ios

I am trying to segue back to a home screen and pop everything from the stack (of views?)
I am using UINavigationController:
[self.navigationController popToRootViewControllerAnimated:YES];
Where shall I call this method? I have tried in -(void) prepareForSegue which does not work.
Basically I want to make sure when I go back to home screen there is no back button on the left of the title.
Home screen here refers to the welcome screen of my App.
I am not sure which part of my code shall be posted. Please comment if you need to see my code.
Thank you in advance.

Assuming you're using a Storyboard, and a UIButton declared over there is the one that triggers that action you wanna perform, you should declare an IBAction: -(IBAction)buttonPressed:(id)sender; in the .h and implement it in the .m. Inside that method should appear that [self.navigationController popToRootViewControllerAnimated:YES]; code. Also remember to attach that action to that UIButton when touch up inside in the storyboard.
Hope it helped!

I think your confusion is around the concepts of what a segue is and how it relates to the navigation controller stack. The stack is exactly the same as the basic data structure stack (http://en.m.wikipedia.org/wiki/Stack_(abstract_data_type)) in that it's a last-in-first-out store. When you segue, you're normally adding to that stack, e.g. Pushing a new VC onto the stack. A back button in most cases would not be doing that. It would be popping, or removing from the stack. Which is why you probably wouldn't call pop methods from the prepareForSegue method. Instead try calling it at some other point, like when they tap the back button, or after some action has taken place.

Related

Segue from screen with several buttons?

I am trying to write an app using UINavigationViewController. My first screen has several buttons on it, and on the click of each button, I want to segue to a UIViewController. I know that I can add a segue on each button, all pointed to the UIViewController that I want to go to, but I was wondering if it is possible to use only one segue that can be fired from each of the buttons.
If that is not possible, I was wondering if it was possible to open the second UIViewController from the first one, on button click, and provide a Back button like the UINavigationView provides. I did manage to get everything on this idea working, except for the back button. I mean I can put a standard button somewhere on the screen and go back, but I'd like the standard back button on the UINavigationView.
Phew! I'm not sure if that makes any sense.
I know that I could also use a tableview, but I'm trying to set this up with buttons.
Thanks
Edit: Thank you to everyone that answered. I now have this working. I would vote up the answers, but I don't have enough posts to do it. I appreciate the answers!
If you need to have separate action functions for each button, suggest that you segue from the main controller to the other controller and create a segue identifier (see xcode procedure below); then, use performSegueWithIdentifier from each of the button action functions. You can also take advantage of the prepareForSegue. To create the segue, control-drag from the left button in the controller in the storyboard to the controller you want to segue to and pick show.
Check the example code in swift that I did for a very similar problem in the SO reference
Linking View Controllers through button
You can embed the main controller in a navigation controller and that will give you the ability to navigate back. If you have multiple layers you can also use unwind segue.
Link each button to one single action (ex. buttonClick) in that ViewController and then perform the appropriate segue using pushViewController method on self.navigationController
-(IBAction)buttonClick:(id)sender {
if(sender.id == self.button1) {
DestinationViewController *vc = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"VC_IDENTIFIER"];
[self.navigationController pushViewController:vc animated:YES];
}
Or if you already have that 1 segue defined in storyboards you can use
[self performSegueWithIdentifier:#"SegueIdentifier" sender:self];
And use that inside the buttonClick method. Using the 1st example, or the second one as long as the segue you setup in the storyboards is a push then you should already get the back button as that is the default behavior for pushing view controllers onto the navigation stack.

Does the method popViewControllerAnimated: act different than the Back button of the NavigationController?

In my Application i have a container ViewController which is the RootView of an UINavigationController.
I transit between various Child ViewControllers through a segmentedControl in the Toolbar of the UINavigationController.
One of the Child views pushes another View on the NavigationController, keeping the ToolbarItems.
Using the Back Button I get the desired behaviour of returning to the RootViewController, but any try of going back programatically won't change the view.
popViewControllerAnimated always takes the topViewController of the Stack but nether updates the View. viewWillAppear of the Container ViewController won't be called this way.
So i am wondering if the Back button does any additional Stuff which won't happen in with popViewControllerAnimated.
Also popViewControllerAnimated:YES will freeze the app without throwing an error.
Thanks for the help in advance.
Edit:
Ok one test case was a little of.
A popViewControllerAnimated in the topViewController of the Stack works as normal. But a call to popViewControllerAnimated through the SegmentedControll does not.
I realise the way i wrote this might be a little confusing, i will try to make this all a little clearer later.
Ok, it was a timing issue. I changed the ChildViews of the container ViewController directly after the call to popViewControllerAnimated.

iOS Showing views conditionally

I have a view in which a user selects an action to take and on that next screen there is a save and a back button. For both of the buttons the last line is dismissViewControllerAnimated:.
I need a way to make the 1st screen show only if the back button is used. save should send back to the main screen/rootViewController I am fairly new to iOS but not programming in general and just need a nudge in the right direction.
Could I set a bool flag to show or not? Maybe I can set the Tag on the view and then check that in the other screens on save/back? I assume I can check the parent view.
Sorry if this is a dup but I cant find anything specifically for this.
EDIT: I am not using a nav controller and am showing the views modally.
The answer will vary depending on how your UIViewControllers are structured and setup. If you're using a uinavigationcontroller then you can POP to the root view controller using:
[self.navigationController popViewControllerAnimated:YES];
If you're presenting your UIViewControllers modally, you can try to dismiss the presenting View Controllers of your modal view controller using the presentingViewController property:
[[[self presentingViewController] presentingViewController] dismissViewControllerAnimated:YES completion:nil];
You may also want to take a look at Unwind Segues if you're using a Storyboard:
What are Unwind segues for and how do you use them?
Finally, as far as determining whether the back button is pressed or another button - that depends on how the app is setup. You'll need to use your own logic (probably if / then statements or case / switch) to determine which button was pressed. You also may want to check out the sender argument in IBActions.
John, to have a UINavigationViewController return to it's root viewcontroller, you use:
[nameOfNavController popToRootViewControllerAnimated:YES];
The other guys are correct that the information you've provided is definitely not enough to determine exactly what you need to do.
You can use the presentingViewController property of a modal view controller to access it's presenting controller.
It turns out that I was using the terminology wrong. I am presenting all views modally and that is the issue, there is no navigation controller. I ended up using NSNotification to build a listener and had the main view controller listen and then dismiss the view and hence show itself. Worked a treat.
here is the link to the code I ended up with.
http://iphonedevsdk.com/discussion/114737/view-heirarchy-issues-possibly-from-the-camera
Hopefully this helps someone else.

ViewDidLoad Method is called again

I have two View Controller. In the first I do some stuff and then I can push the second View Controller by clicking a button (the button connected with the other ViewController in the storyboard). There I can do some settings and so on. I get back to the first View Controller with the button "Done". But then the ViewDidLoad method is called again and all the "stuff" (text in textfields, ...) is gone.
I hope you guys understand my problem.
Why? And how can I disable this?
How are you going back to the first view controller from the second one? I think your problem is you're re-instantiating the first view controller when the user hits "Done".
Instead, you should be using either "popViewControllerAnimated" or "dismissViewControllerAnimated" to go back to the first view controller.
e.g: (one of these 2 should work):
[self.navigationController popViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:nil];
Maybe the firstViewController is unLoaded because of receiving memory warning. So when it opened again, it calls ViewDidLoad

Pop the current view using Segues/Storyboard on iOS 5

I am creating an app using iOS 5 SDK. I managed to push views using the Storyboard's Segues, but I cannot find the proper way to pop the current view and go back to the previous one.
I am not using any navigationController (the app doesn't have any top or bottom bars).
I don't think using modal or push segue the other way would be the solution as it instantiates a new controller.
Do I have to use a custom Segue with the opposite animation and deletion of the view at the end ? Or is there a better way ?
Storyboards in iOS 5 don't provide a "no-code" way to return from a segue -- that's something you'll need to implement yourself.
If you use "push" segues (which require a navigation controller), use the navigation controller's popViewControllerAnimated: method to undo the last push segue. (Or other methods to undo more; see the UINavigationController documentation.)
If you use "modal" segues, call dismissViewControllerAnimated:completion: on the view controller which presented the current view controller (which you can get from its presentingViewController property).
Update: In iOS 6 and later there's unwind segues for going "back" in a storyboard. It's still not a no-code solution -- and it shouldn't be, because you need to be able to do things like differentiating between "Done" and "Cancel" exits from a modal view controller. But it does let you put more of the semantic flow of your app into the storyboard. Apple has a tech note that describes them in detail, and they're also covered in the video from WWDC 2012 Session 407.
You could try calling [self dismissViewControllerAnimated:YES completion:nil]; from the controller you want to dismiss (whether the controller has been pushed, or shown modally).
Here is the related documentation : UIViewController Class Reference
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.
Just to clarify.
In the class that was pushed. Simply wire up the following and the controller and view will be popped off.
[self.navigationController popViewControllerAnimated:YES];
Create Segue type "Custom" on your stroyboard. This can be from a button.
Create a new UIStoryboardSegue class named "popSegue"
In the popSegue.m file add the following;
-(void)perform{
UIViewController *sourceViewContreoller = [self sourceViewController];
[sourceViewContreoller.navigationController popViewControllerAnimated:YES];
}
-In the storyboard editor.
-Select the segue and change the Segue Class to "popSegue"
-Set the Identifier to "popSegue"
Done!
You can use the same "popSegue" class throughout your project.
Hope this helps
I'm using Xcode 5 also and here's how it's done. First, in the view code file that pushed the other, create an IBAction method in the .h file such as this:
- (IBAction)exitToHere:(UIStoryboardPopoverSegue *)segue sender:(id)sender;
Then in the .m file add this:
- (IBAction)exitToHere:(UIStoryboardPopoverSegue *)segue sender:(id)sender {
}
You can add any cleanup code you want executed in this method. Next go to your storyboard and select the pushed view. I assume you've got some kind of button on the view that the user taps to signal he's finished. Click on that button, hold down the key and drag to the the green box below the view which is the Exit. Release the mouse button but continue to hold the key. A popup will appear and your method will show in the list. Select that method. Now when the user clicks on the button, the view will pop and you'll be returned to the starting method.

Resources