I am trying to understand modal vs push segue and read few Q & A like this and this. One point I am confused from these answers is "The presenter should take care of dismissing the VC it presented."
For example, the example I am writing shows UIPageViewController something like the example available here, with a button at bottom of the page with name "Skip".
In story board I have created a segue (of type Modal) from "Skip" button to another "View Controller" (let us say LoginViewController), but where do I need to dismiss the UIPageViewContoller (if at all required) and how?
EDIT:
After little bit more reading, it seems UIPageViewController (Which has Skip button) should take care of dismissing LoginViewController (because UIPageViewController is the presenter).
In my case, after Login complete, I would like to navigate to "Menu" page, then how can I ask UIPageViewController to dismiss the "LoginViewController" and move to MenuController? I couldn't find any example on how this works.Any help would be appreciated!
As per the tutorial link you have given in question.
There is a APPViewController which is root for the UIPageViewController and also in AppDelegate, so on top of that view, require a Skip button which is above all the subViews in AppViewController. So its IBAction event will be in AppViewController only.
Now first change your AppDelegate self.window.rootViewController to LoginViewController.
In LoginViewController viewDidLoad event, presentModal UIPageViewController.
Now in its action event of skip button, you can write like this:
[self dismissViewControllerAnimated:YES completion:nil];
So it will automatically dismiss all your AppChildViewControllers, and will display LoginViewController, which is already behind.
This is just a base logic to achieve your goal, you might require to change code as per your project implementation.
Hope this helps.
First dismiss the UIPageViewController and then using delegate or block methods (whatever suitable) to get notified when you press the skip button in the parent controller and then calling LoginViewController.
Related
I use storyboard with identifier, when i want to call some view, I use this code:
ViewB *view = [self.storyboard instantiateViewControllerWithIdentifier:#"View2"];
[self.navigationController pushViewController: view animated:YES];
But I want to do something when i pressed the back button, How can I know that happens this ?
That depends on what you are really up to.
First of all you cannot directly catch such an event or so. Unless you replace the back button with your own back button, assign yours to an action of yours and go from there. Within this action you can perform what ever you want to do. And you will have to care for calling popViewControllerAnimated: yourself.
If you don't really need to know that the button was pressed and just need to react when ever the view controller or its view respectively disappears then you can overwrite viewWillDisappear or viewDidDisappear. But be aware that these methods are called too every time when another view is pushed ontop of your very view.
viewWillUnload or viewDidUnload is probably more what you are looking for.
However, dealloc is called when the view controller is destroyed.
One of these will do depending on what you really need.
i've embed my first ViewController in an navigation controller. This auto generate an back button to all the ViewControllers.
The problem is that when i save a video into my core data it automatic go to a new ViewController, but then i'm able to go back to the ViewController where i added the video. Is there a way to like delete/reset the former ViewController that has presented and therefor control how far you can go back by clicking the back button?
Or what would be the best solution?
It's hard to offer advice without seeing your exact use case, but it sounds as though instead of pushing a viewController onto a navigation stack, you might want to do something like present a modal viewController.
Instead of doing pushViewController:animated, try [self presentViewController:newViewController animated:YES completion:nil]. If you're presenting your viewController via a segue in Interface Builder, change the segue type to 'modal'.
You'll also then need to add a button to dismiss your viewController - you can use the [self dismissViewController:animated:completion] method.
I have an app with several views. Taking into consideration the large main view, called MyView1, it is controlled by MyView1Controller. Within MyView1, there is a button that causes a modal segue to another view, whose controller is also MyView1Controller. This modal view has a couple UILabels, and a button that terminate the modal view, bringing the user back to MainView1.
Here is the problem... Let's say in my modal view there is a UILabel called sampleLabel. While in MyView1, a button is pressed, which executes the code:
sampleLabel.text = #"changed";
Since the UILabel named sampleLabel is not on screen for MyView1, and instead is part of the modal view from MyView1, nothing happens. However, when I click on the button to view the modal view from MyView1, the UILabel hasn't changed.
This is even more puzzling since the main MyView1 and the modal view that segues off of MyView1 are controlled by the same view controller, MyView1Controller.
Can someone please tell me how I can make code that executes during the user's interaction with MyView1 change things in the modal view, so that when they press the button and segue to the modal view, the UILabel's have already been changed?
Thanks!
First of all, Apple recommends (and it makes life a lot easier) to have one view controller for each view. So you should have a second view controller. In the second view controller you would have a property called sampleLabel. In the first view controller you could use different methods to set the sampleLabel.text. I would probably create a separate sampleLabelText property in the first view controller (could be an NSString *) and set it to the text you want when the user presses a button. Then in your
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
you would get your second view controller and set its property like this:
SecondViewController *svc = [segue destinationViewController];
svc.sampleLabel.text = self.sampleLabelText;
That's it. Hope this helps.
So I have had a similar issue that I resolved through 'delegation' but not through a segue schema. Here is a link to the stackoverflow question and my answer. Delegation
Hopefully this gets you going in the right path. Instead of modally presenting a view, I push a new viewcontroller onto a navigation stack but the same answer should apply, hopefully :P
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.
Hi there and thank you in advice for your help. I have a really strange problem while working with ViewControllers in Xcode4. First of all I have to say that I'm not using storyboards and I prefer to create any UI element programmatically. So I've set a UIButton and I want that, when pressed, it brings me to a new view controller. This is the code I'm using for a button:
-(void)settingsAndExportHandle:(UIButton *)buttonSender {
SettingsViewController* settingView = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
settingView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:settingView animated:YES];
}
This buttons is initialized and allocated in the viewDidLoad method of the RootViewController. I want to switch to the other view controller (in this case SettingsViewController) when I press the button.
The strange thing is that when I press the button, the animation that flips the controllers goes well, but when it finishes I obtain the EXACT same things that I had on the RootViewControllers (same custom views, same buttons, same all!). The question is: what I'm missing?? I have to say that I use ARC (automatic reference counting) so I can't release or dealloc the views and buttons I've created on my RootViewController.
Any help will be appreciated. Thank you all!
Pushing and and modally presenting view controllers does not deallocate the view controller that presented them. It simply adds the additional view controller to the stack. You'll need to implement a callback method so that when the user hits the button to flip back to root view controller, your settings view controller lets the root view controller know what's about to happen so you can call a method you've written to reset the interface back to whatever state you need it at. You may also be able to use viewWillAppear: but that's a little messy.
However, according to the Apple Human Interface Guidelines, the user expects that when they push a view controller or modally present it, the view controller they were on will save state and be exactly the way they left it when they came back. It's disconcerting and annoying when state is not preserved while in a navigation controller context. It is especially annoying when it's modally presented.
Think about this - A user is in a hypothetical Mail app. They start typing out an email and set a font size and a color. They tap on the add attachment button, which brings up a modal view controller that allows them to select a picture. They select the picture and the modal view is dismissed, and in your implementation, the mail composing interface would have reset and the email content would be gone or at the very least the selected font size and color would be back to the default. That's not a good experience.