I'm trying to get a storyboard to bring the user back to the first screen of a storyboard when a button is pressed.
I have the button click hooked up and the method is hit when it's tapped but it's either doing nothing or crashing the app depending on what I've got in that method (I've tried so many things at this stage that I can't remember the original setup)
The best I can achieve is that once tapped the user gets brought to the third screen in the storyboard, rather than the first.
Here's the storyboard, I want to get the user to move from the button circled in red back to the very first view controller (top left of screenshot).
Maybe the storyboard layout will help people, I'll post some of the various methods I've tried as well.
Here's the method
- (IBAction)done:(id)sender
{
//Multitude of attempts have been in here, either they don't do
//anything or they just send the user back to the NEW REPORT screen.
//Button does nothing in these following events
[self.navigationController popToRootViewControllerAnimated:YES];
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
}
If you want to start fresh, have the button instantiate a new instance of the first controller, and set it as the window's root view controller:
FirstViewController *first = [self.storyboard instantiateViewControllerWithIdentifier:#"First"];
self.view.window.rootViewController = first;
It's not clear to me exactly how you're getting to that controller with the button in question, but you might want to put dealloc methods in all your controllers with a log to see if all are getting deallocated at some point in your navigation, and when you go back to the new first controller as I've outlined above.
Related
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.
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.
So on my center viewcontroller of my app I have a mapview. I click a button and it toggled my left viewcontroller and displays my left view controller. While I have my left viewcontroller open, I click a button and it closes the left viewcontroller and calls a method inside of the center view controller. It does actually call the method, but I think it is on another instance of the center view controller, because it does show NSLog, but it actually doesn't update information on the center view controller.
So basically, my issue is that I 'think' its creating multiple instances of the center controller. How an I access the FIRST instance to update data on it?
EDIT: Okay so heres some code.
FirstViewController *controller = (FirstViewController*)[self presentedViewController];
[controller doSnap];
I've tried several variations of this. Inside the method 'doSnap' I have an NSLog, and I have it do some things on the mapView. The stuff ends up getting logged, but it does not actually display on the map, and I think the reason of this is because it is a different instance of the view controller.
When using modal segues, you can just use the presentingViewController property to access the viewController that you came from.
YourOriginalViewController *controller = (YourOriginalViewController*)[self presentingViewController];
controller.yourPropertyToSet = whateverValue;
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
I'm viewing a detail view when clicking on a record from the table. When I call the back button from the detail view using
- (IBAction)loadDispensary
{
[self.navigationController popViewControllerAnimated:YES];
}
I get the unrecognized selector error.
I've tried pushing the the detail controller the following two ways.
Push type 1
detailViewController *detailView = [[self storyboard] instantiateViewControllerWithIdentifier:#"detailView"];
detailView.strain = self.selectedStrain;
[self.navigationController pushViewController:detailView animated:YES];
Push type 2
[self performSegueWithIdentifier: #"detailSegue" sender: self];
//Set the strain on the prepareForSegue
how the button is connected? can u show the code? perhaps you might have not properly linked the button to the IBAction.
I think you may be trying to pop a view controller that is already popped. If you have a UINavigationController and you "Push" a view controller through a segue, the back button that is displayed at the top left of the screen is already configured. You should not have to put one there yourself. If you programmitically place a button in the left bar button position it will display in place of the UINavigation's button.
Try removing the button and allowing the UINavigationController to manage going back and see if that works better.
Someone had asked me to paste the full error code and when I went to do that I saw that the method the button was pointed to was no longer there, so it was trying to call a method that didn't exist.