Back button doesn't appear in navigation bar - ios

I'm having trouble understanding the way view controllers are presented and how to navigate between them in swift. I have a contact list, when you click on one contact it opens the related conversation, but it doesn't show any back button to the conversation list. My storyboard is :
Contact List -> Navigation Controller -> Messages Controller
There is no navigation controller before contact list because it messes up with a sliding menu.
Here is my code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowConversationFromSelectedContact" {
let nav = segue.destinationViewController as! UINavigationController
let cdtvc = nav.topViewController as! MessageViewController
cdtvc.currentConversation = openConversation
}
}
More generally if you could explain or have any good ressource about the way stack of controllers work and how to navigate between them it would be great, I read a bunch articles but it's still unclear.

Re-arrange it so it is Nav Controller -> Contact list -> Message controller, and use push segues (if you're using swift 1.2+, they're called Show segues).
Inside prepareForSegue: you don't need to do anything else besides setting the contact id (or whatever data you need to pass) to the message controller.
Edit:
For a sliding menu, I suggest the following navigation model:
The Storyboard ViewControllers hierarchy goes
Nav Controller --root segue--> Contact List VC --show segue--> Message VC
Sliding menus are usually to present Top Level Views. Your Contact List VC is a top level view. Since it is also the root VC, you can use self.navigationItem.leftBarButtonItem to assign a button to show your sliding menu.

Related

How do I switch between screens via the menu? A big error appears. Swift

I have a navigation controller and several view controllers. When I click on a table cell in the Stocks View Controller, I open the Stock Chart View Controller. In it I have 3 buttons "Chart", "Summary", "News". I want to click on "Summary" to move to the Stock Summary View Controller, but an error occurs for several dozen lines. How can I implement transitions in such a menu?
And how do I click on" back" in Stock Chart View Controller and Stock Summary View Controller to return to Stocks View Controller?
Code for switching from the Stock Chart View Controller to the Stock Summary View Controller:
#IBAction func onSummaryButtonTapped(_ sender: Any) {
let storyboard = UIStoryboard(name: "Main", bundle: .main)
let viewController = storyboard.instantiateViewController(identifier: "StockSummaryViewController") as! StockSummaryViewController
navigationController?.pushViewController(viewController, animated: true)
}
Storyboard:
enter image description here
Your App:
NavigationVC > StocksVC (tapping on a cell) ➡ StockChartVC > StockSummaryVC > etc.
➡ is important here, how do you navigate from StocksVC to StockChartVC? Do you push StockChartVC or present modally? Since you do segues programmatically, it can't bee seen in the image.
I can provide the following info to help you:
The push-style navigation automatically contains/adds controls for backward navigation because it adds all ViewControllers to its navigation stack; all ViewControllers will be embedded in the same NavigationController
In case of presenting scenes modally, these ViewControllers have to have their own NavigationController. thus, your StockChartVC has to be embedded in its own NavigationController
I believe you do the push-style segue from StocksVC to StockChartVC and also pushing from StockChartVC to StockSummaryVC; in that case, there should be no problem at all. Moreover (as I wrote), all they VCs will be added controls for backward navigation. Everything will be working just fine!
So pay attention how you are segueing and according to that, implement the right navigation.

How to segue from tab bar view controller to another view which is a child of a navigation controller

I laid out my home screen (Summary screen) as shown on the screenshot below:
I added the "+" button on the UITabBarController subclass. This button will segue to a view controller and show it modally. To give you a bit of context on how I've structured my storyboards, please refer to the screenshot below:
This modal view controller has a form that the user needs to fill in, and once they're done, there's a 'Done' button which will 1) dismiss the modal, 2) take them back to the root view which is either the 'Summary' tab or the 'Details' tab then 3) take them to a list view showing the most recent data they've entered on a list (destination view – highlighted in red).
Now, doing the segue when the user taps the "+" button is simple enough. With the following code:"
menuButton.addTarget(self, action: #selector(menuButtonAction(sender:)), for: .touchUpInside)
then
func addNewExpense(action: UIAlertAction){
self.performSegue(withIdentifier: "segue_formModal", sender: self)
}
On the modal I've setup a protocol which will then send the form data back to the tab view controller.
extension XtabBarViewController: NewInfoDelegate{
func newInfoSubmitted(formData: FormData) {
performSegue(withIdentifier: "segue_ListingPage", sender: self)
}
}
But it seems that the perform segue is not working. It says the segue does not exist. "segue_ListingPage" is that segue that connects the Summary view and the destination view.
How can I segue from the tab bar view controller to the destination view? Any help is appreciated.
Thanks in advance!
You can just make the navigation view controller the entry point.
I figured it out on my own. For the benefit of those who run into the same issue here's my solution.
I simply added the code from the tab bar view controller the code:
let childVC = children[0].children[0]
childVC.performSegue(withIdentifier: "segue_TXListPage", sender: self)
So what I did here is call the performSegue from the view controller that segues to the destination controller.

View controller view getting misplaced when navigating back to the home screen of UITabbarController

I have a tabbarcontroller in my application and have added view controllers with the help of storyboard and segues,
When i am in the second tabbar item I have a table view embedded with a navigation controller filled with usernames and on top I have a hamburger icon, I select a particular item from the table list present in the hamburger icon and navigate to the details view controller I have used segues and given below is the code for the same
self.performSegueWithIdentifier("MY_DETAIL_SEGUE_NAME", sender: nil)
MY_DETAIL_SEGUE_NAME is actually a custom push segue of the SWRevealViewControllerSeguePushController, the push is working fine and i am able to navigate to the details screen.
The Problem: Since I am in the second tabbar item on the hit of back button i need to show the inital view / home view controller of the second tabbar item which is the friend view list, so on the back button i have written the below code in the detail screen
#IBAction func moveBackToController(sender: AnyObject) {
self.performSegueWithIdentifier("showFriendListPage", sender: nil)
}
showFriendListPage: This is a custom segue to the firendlist page using the SWRevealViewControllerSeguePushController and is pointed to the tabbarcontroller
To highlight the second tabbar item i have used the below code written in the detail screen
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
let objParentTabbar = segue.destinationViewController as! ParentTabbarController
if segue.identifier == "showFriendListPage" {
objParentTabbar.selectedIndex = 1
}
}
What happening here is when i navigate back to the home screen of the second tabbar item my view is distorted i.e. the UI elements are not placed in a correct order which they were when i first went to the second tabbar
Note: All my view controllers are embedded inside the navigation controller so the structure is
TabbarController----->NavigationController------>ViewController
Please suggest where I am going wrong and what needs to be done to resolve this, my only struggle is the view getting distorted and i dont really know why is this happening.
Call the view your controller via code in your application should do the trick
objParentTabbar.selectedViewController?.viewWillAppear(true)

navigating through desired views (while skipping some views) using UINavigationBar back button

I am using a UICollectionView to show a list of images.
1)By clicking on any cell the image and some description about it is displayed in the resulting view controller(using a push segue).
2)When i swipe from the left/right edge(using PanGesture) i need to display the details of the previous/next image in the collection view.
3)But the back button of the navigation bar has to take me back to the collection view and not to the previous displayed details (shown by the PanGesture).
I know how to get 1 and 2 done but don't have a concrete idea to get the 3rd job done.
Any help would be appreciated.
You can find your desired UIViewController in your navigation stack using for loop. Try this. This is in Swift
for (var i = 0; i < self.navigationController?.viewControllers.count; i++) {
if (self.navigationController?.viewControllers[i].isKindOfClass(YourViewController) == true) {
println("is sw \(self.navigationController!.viewControllers[i])")
(self.navigationController!.viewControllers[i] as! YourViewController)
self.navigationController?.popToViewController(self.navigationController!.viewControllers[i] as! YourViewController, animated: true)
break;
}
When you navigate from one view to another (e.g. by showing a detail view of your images one after the other, then all these views are internally piled up as a stack.
Thus, if you want to jump directly to a view somewhere in between this stack (e.g. the collection view), then you can use the Unwind Segue.
In your case it should work like this:
First, in your collection view (i.e. your back button destination) you need to implement a UIStoryboard Segue as follows
#IBAction func myGoBackPoint(segue: UIStoryboardSegue) {
println("Jump directly back here from any other view")
}
Then, in the storyboard of your detail view you ctrl-drag directly to top rightmost Exit marker and choose the previously created back button destination:
In the code of the detail view implement the "go back instruction"
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "My Unwind Segue" {
if let myUnwindSegue = segue.destinationViewController as? MyCollectionViewController {
// prepare for segue
}
}
}
Hope this helps.
Finally after researching a lot i found that using a collection view with each cell taking up the whole screen is the best way to go about solving this issue.
Thankyou

Multiple unwind in the same button - Swift

I would like to know if it is possible to assign two different unwind method at the same button. For example:
I have this views navigations:
Home->A->B
Home->C->B
A and C views navigates to B, but then I want to return to previous views using the same B view and controller.
It is possible?
I have been thinking about write assign unwind method to the button programmatically depending what view comes.
Thanks in advance
I'm sorry about my english, is not good.
Here's a Swift solution that worked well for me. The code below only works if you hookup your segues correctly in the storyboard and in code. Checkout this page for great explanations on setting up unwind segues.
In summary:
You're accessing the same view from multiple other views. So, when you segue to a view, you can pass the source view controller (the view that you're currently in) to a property in the view that you're going to.
In your view that you will unwind out of, you can check the property holding the info (the class) on where you came from, and then perform a segue based on what view it is.
The code: (using ex: Home -> A -> B or... Home -> C -> B)
Note: B is the view that will unwind to multiple different views.
In A or C: (code works the same way in both views)
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "segueIdentifierInViewAthatGoesToViewB" {
let controller:B = segue.destinationViewController as! B
//the code below passes our current view controller class to a property in view B.
//So, view B will know what view we came from.
//In our example, we're coming from view A or C
controller.viewControllerNavigatedFrom = segue.sourceViewController
}
}
In B:
//setup an IBAction that will check the source view controller (that we passed when we segued to this view) and perform a segue based on where we came from. You can hook this up to a button or anything you want really.
//isKindOfClass(A) - "A" would be the name of your class
//setup a property to receive the view controller class where we are coming from
var viewControllerNavigatedFrom:AnyObject?
#IBAction func myButtonPressed(sender: AnyObject) {
if self.viewControllerNavigatedFrom!.isKindOfClass(A) {
//Unwind to view A
performSegueWithIdentifier("unwindFromBbackToA", sender: sender)
}
else if self.viewControllerNavigatedFrom!.isKindOfClass(C) {
//Unwind to view C
performSegueWithIdentifier("unwindFromBbackToC", sender: sender)
}
}
Although, question isn't very clear. But what I could understand is that you want to navigate back to the previous view i.e. B>C or B>A depending upon where user came from.
If so, then check the UINavigationController. It keeps track of the navigation history and automatically adds a back button. Kind of like the back button in our browsers.
Here is a tutorial, although a bit old: Link

Resources