I have an iOS app with 3 views. I am using a "push segue" to move between them. I have linked a push segue from a button in First view to Second View. For moving from second to third, I cannot have a button. I have a list of items and the person can click in any of those to move to third(and last) view. So I added a segue in storyboard and calls it programmatically. The third view is opening properly except that the nav-bar is no longer there.
[self performSegueWithIdentifier: #"moveToFilesSegue" sender: self];
I can live without nav-bar. But the real problem is that I cannot do a push segue from my third view to any other view.
So my question is whether there is a way to call a segue from second view to third view in such a way that the third view also has the navigation controller that the first two have by default(ie navbar is also visible in third segue). There is some break in navigation because of me calling a segue programmatically.
So a few comments. If you would like to be able to get to the two other views from any view at any point in time, then I would suggest using a tab bar controller rather than a navigation controller.
If you must use a navigation controller, then you should keep the first view controller as the root view controller. Imagine then tapping a button that pushes the second view controller. Then say you tap a button to get to the third view controller from the second. What you should really do is perform an unwind segue from the second and then immediately perform a segue to the third. The animations will be a bit undesirable by default since it will probably show the pop and the push, but to treat it like a tab bar, you could just disable the animations on the pop and push.
To implement, keep an int variable in the first view controller (btw.. you can do this by keeping the int in the navigation controller as well if you want). In the viewDidAppear, check the int variable. If it == 1 then push the second view controller. If it == 2, then push the third view controller. Else, don't do anything. When a button is pushed in the second view controller to view the third, unwind the second view controller, but in prepareForSegue set the int variable in the destination view controller to 2 . Thus, when the first view controller appears, it will immediately push the third view controller.
I know it is a bit annoying, but you don't really want to keep pushing the same view controllers over and over again without unwinding.
Related
I'm developing a simple iOS app to learn Swift and iOS programming.
I was wondering what would be the "best" way to present, on app launch, a different View Controller than the first one in the Navigation Controller stack.
Consider this storyboard diagram:
The Tab Bar Controller is the initial View controller and "View Controller 1" is shown at app launch inside the navigation controller. Since "View Controller 1" will be almost never used, I'd like to show "View Controller 2" instead, with the "back" button pointing to "View Controller 1". To save time and memory, I'd prefer non to load "View Controller 1" at all, since I already know what data has to be shown in the second view controller.
Both the view controllers are actually Table View Controllers and the selection of one of the cells in the first VC triggers a segue to the second. However the user would usually only need to see the second VC as if the first cell of TVC 1 was selected.
Because you want to be able to "go back" to the first VC, it needs to be put below the second one. My suggestion is to programatically set up the first VC as the root view controller in appDelegate didFinishLaunchingWithOptions and immediately push/present VC2. In this way the first VC won't be shown and therefore costly views loading/laying out subviews can be omitted.
I have a TabBarApplication with four views in the main TabBarItem. The problem comes when I go to any of these views and click in any button to go to another view and when I go back by a button linked to the main view, the TabBarItem of the app disappear!!
For example, one view of the app is a tableView in which each element of the list is linked to his external view and it has a back button that should return to the tableView. All the segues are by modal, not push because push segue crash the application and by modal it runs correctly but the problem comes when I returned by clicking the back button of the NavigationItem in the header of the view to his main view and the TabBarItem of the app is not there, is empty.
Each tab should have the view controller set to a navigation controller, with the view controller you want set as the root view controller of the navigation controller. Now you can use push segues and the standard back button that will be added for you. This will bypass the issue (and work much better for you and users).
You current issue is likely related to not really ever going back. Instead, just always presenting new modal view controllers which replace any existing content on screen.
in the top view of my view controller (the last table view controller) has an add navigation item. i added a view controller object from the objects library and i ctrl + dragged from the plus button to the view controller. i tried the app and it works fine but i can't go back to the previous controller when i reach the last controller. since the last controller connected (by segue) to the plus button, i can't have a navigation bar on top. so i added one and added an navigation item called it Done. i created an IBAction method in the class that the last controller subclasses which have the following code:
[self.navigationController popNavigationControllerAnimated:YES];
However, when i run the app and press the Done button to go back, it doesn't work although i feel like what i did is totally legal.
If you would have made the final view controller segue a Push segue, you'd still have the navigation bar with a back button. It makes sense since you're adding a record that you'd want a modal view.
You can dismiss the current modal view with the following code:
[self dismissViewControllerAnimated:YES completion:nil];
Generally, you should use delegation and dismiss it from the presenting view controller. However, I think it's fine to dismiss yourself if you're using storyboards, segues, and ARC.
Did you create a Bar Button Item and assigned its 'selector' callback?
I have a main ViewController that has two buttons that each segue to their own table view. The table view cells have a title and a subtitle and I have managed to load my content into them.
When I click the item, I want it to bring me back to my main view controller along with the title string and the subtitle string.
Should I be using a push segue or modal segue?
On my main view controller I have Labels that I want the strings to change to.
If you need more information, let me know.
You should likely use neither a push, nor a modal segue if you want to go "back" to the main view controller. So long as this is contained within a navigation controller, it sounds like what you want to do is forward the data you collected from the cell to the main view controller somehow, and then pop the current view off the navigation stack.
If you were to use a push segue, then the main view controller would be on the navigation stack twice.
If you were to use a modal segue, you might end up with numerous navigation stacks floating around in modal view controllers all over the place.
In my app delegate I create a UISplitViewController. I set the delegate to be the detailViewController.
When I run my app in portrait, I have the left top popover button showing that will slide out the split view master.
Then I have a button in my detail view that resets the splitviewcontroller array with a new detail view controller and sets the split view delegate to that controller.
The second detail view displays properly... but I lose my popover button on the second view controller.
Does anyone know how I can get that button to remain on all of my detail view controllers I may add?
Thanks!
See http://www.raywenderlich.com/forums/viewtopic.php?f=2&t=1546 for what I find to be a good approach.
It involves setting the SplitViewController delegate to be the master instead of the detail. The master keeps references to the popoverController and the button, and each time the delegate methods are called (hide and show master) it gets the current detail view and performs the necessary action (add in the button/remove button and popovercontroller).
The master defines a protocol for "SubstituableDetailView" which contains the two methods for showing/hiding the button.