Back Button shows in StoryBoard but not Simulator.
I added a segue from TableViewController to DetailViewController to pass data. The Storyboard automatically shows a Back Button on DetailViewController, but when I run the Simulator, the button doesn't show up.
This is my Storyboard:
A closer look of TableViewController and DetailViewController:
But in my Simulator the button doesn't show up:
The hierarchy of the whole project:
I want to know where to configure the back button(in my segue?), or instead deleting the button(not letting it show in the Storyboard) so I can create one myself.
The code of my segue in my TableViewController:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showDetailView", sender: indexPath)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch (segue.destination, sender) {
case (let controller as DetailViewController, let indexPath as NSIndexPath):
controller.receivedName = storeList[indexPath.row].name!
controller.receivedDesc = storeList[indexPath.row].desc!
controller.receivedRate = storeList[indexPath.row].rate
controller.receivedUrl = storeList[indexPath.row].url!
default:
print("unknown segue")
break
}
}
Your initial view controller in the storyboard is actually the TabelViewController (you can see there is an arrow to it).
Thats' why when you start the scene and the TableViewController shows but it is not embedded in the navigation because the navigation controller has never been created.
Just change which is the initial view controller to be the navigation controller or any other before the navigation controller which holds the TableViewController.
You can just drag the arrow to change the initial controller in the storyboard
Related
On photo below I show you my storyboard. On TableView Controller I have expandable menu. What I cannot achieve right now is to switch on second tab bar item (green one) and let it know what is ID of selected menu item. Between tab bar controller and green and blue controllers I have relationship "view controllers". I tried to call directly green view controller with this code:
let secondTab = self.storyboard?.instantiateViewController(withIdentifier: "secondstoryboardid") as! SecondVC
self.present(plavi, animated: true, completion: nil)
This code displays second tab view but without tab bar and everything derived from container view.
If you configured correctly such storyboard, you should get the reference to the UITabBarController through prepare(segue), doing so:
private weak var tabBarViewController:UITabBarController?
// be sure to add prepare inside your segue manager (the container in this case)
override public func prepare(for segue: UIStoryboardSegue, sender: Any?) {
self.tabBarViewController = segue.destination as? UITabBarController
}
besides you may want to declare an enum to have a clean access to the embedded view controllers:
enum TabType:Int {
case blue
case green
}
thus you might define a function for injecting the selected indexPath, doing something like:
func inject(indexPath:IndexPath, into tab:TabType) {
if let greenVc = tabBarViewController?.viewControllers?[tab.rawValue] as? GreenViewController {
greenVc.selectedIndexPath = indexPath
tabBarViewController?.selectedIndex = tab.rawValue // this will auto select the TabType viewcontroller
}
}
finally whenever you have to change the current selection, you may call inject with the new indexPath:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.inject(indexPath: indexPath, into: .green)
}
Note
Call instantiateViewController means making a new "fake" view controller, which is a wrong approach, since you already have it embedded in your UITabBarController.viewControllers
I've just recently started learning about Xcode and the swift language. To get myself familiarise with them I'm trying to build a simple app with what I've learnt so far. 1
The screenshot shows what I want to achieve. VC1 and VC2 are both a navigation + tab VC. When the user taps on the "Preset" button on the navigation bar of VC1, the screen will switch to VC2 which has a table with different preset values. What I did was to create an action segue (show) from the "preset" button to VC2. All good so far.
This is what I want to do but couldn't figure a way to do it: At the table at VC2, when the user click on any row, he will be brought back to VC1 and the value in the selected row is being inserted into a textfield in VC1.
What I had tried to do was to create an action segue (show) from the table cell to VC1. But by doing so, the navigation bar and tab bar on VC1 and VC2 has disappeared 2
Is what I'm trying to do achievable? if yes, what did i do wrongly?
I tend to use storyboards with an IBAction to return to the previous view controller, such as
#IBAction func userDidSelectTableCell() {
self.navigationController?.popViewController(animated: true)
}
But in your case I think your after a unwind segue, I've not used one but you can read more about them at this following link https://spin.atomicobject.com/2014/10/25/ios-unwind-segues/.
Hope that helps
For your purpose you need to use a unwind segue. In order to achieve this, you firstly need to declare a global variable in your VC2 class which stores the value of the selected row. You can use the didSelectRow method for that.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedCell = indexPath.row
self.performSegue(withIdentifier: "YourIdentifier", sender: self)
}
you need to add a #IBAction method in you VC1 class.
#IBAction func unwindtoVC1(_ sender: UIStoryboardSegue){
if let sourceVC = sender.source as? YourTableViewController {
yourTextFiled.text = sourceVC.selectedCell
}
}
In you storyboard, in VC2, Control+drag-drop from viewController to Exit portion to create a segue.
From the pop-up that comes, select the unwindtoVC1 method.
Now, select the segue and in the attributes inspector, give it any identifier.
Use this identifier in your VC2 class, in the didSelectRow method, in the self.performSegue(withIdentifier: "YourIdentifier", sender: self)
Hope this helps.
I am looking at using a collectionView for a menu within an app. I want the menu to have a navigation controller so the user knows they're in the menu and can go forwards and back between the menu and the page selected from the menu.
However as i have created the collectionView programatically i don't seem able to use a 'show' segue as the cells are created at runtime.
Interface
Runtime
Is there a way of still utilising the navigation bar for this menu?
I was previously using a static tableview with segue from each cell to desired page. Ive got a bunch of code tied into each named segue so am reluctant to change.
Code using segues on the old tableview
class MenuTable: UITableViewController {
weak var centerButtonDelegate: ManageCenterButtonDelegate?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueTour" {
fadeOutDelegate()
}
I think you should perform the segue programatically if you are linking a UICollectionViewCell to a new ViewController, they are way more easy to control, might be as well that you set it wrong in the storyboard too.
In your tableView delegate method 'selectedRowAt: IndexPath' you should do a switch statement and perform the segue there. Something like this:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
switch indexPath.item {
case 0:
//perfrom segue
performSegue("mySegue", sender: self)
default:
break
}
}
When the cell is selected or tapped (or however you want to detect this), create the next view controller and configure it appropriately to that cell, and call show.
In my project, I have a few View Controllers and I use UINavigationController.
When I make a seque from UIViewController to UITableViewController I have "back" button added automatically, but when I make seque from UITableViewController to UIContentViewController tapped a cell, I don't have a "back" button in UIContentViewController.
Plan of my app is here
The segue in UITableViewController looks like that:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let CV = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController
let tnumber = tableView.indexPathForSelectedRow?.item
CV.titleContent = daneOWpisach?[tnumber!]["title"]
CV.webContent = daneOWpisach?[tnumber!]["description"]
CV.category = category
self.presentViewController(CV, animated: true, completion: nil)
}
What should I do, if I would like to have a back button in UIContentViewController added automatically?
In your code you are presenting the view controller on cell selection..! Back button will show only if you perform push not on presenting the view.
In the above diagram what I have seen is you already make the segue from UITableViewController to UIContentViewController. select the segue and go to attribute inspector give the identifier for the segue.
On the cell selection perform the segue action with the identifier you specified
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("Your Segue name", sender: sender)
}
If you want to pass data to destination view controller, do it like below..
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "Your Segue name" {
let CV = segue.destinationViewController as! ContentViewController
let tnumber = tableView.indexPathForSelectedRow?.item
CV.titleContent = daneOWpisach?[tnumber!]["title"]
CV.webContent = daneOWpisach?[tnumber!]["description"]
CV.category = category
}
}
Hope this helps you
I have created a custom cell and want to perform a segue to another ViewController by clicking on it.
I used didSelectRowAtIndexPath method and performed a segue but no result. The segue does not work!
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("toDetailViewSegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath = tableView.indexPathForSelectedRow;
let cellname = tableView.cellForRowAtIndexPath(indexPath!) as! CardTableViewCell;
let DetailViewController = segue.destinationViewController
DetailViewController.title = cellname.textLabel?.text
}
Check the following items:
First, make sure that you established your segue. In your table view controller, control click on the yellow icon at the top of the table view controller's scene in the storyboard. Drag it to your destination view.
Second, make sure that the name of your Storyboard Segue matches the desired value (toDetailViewSegue).
In your storyboard, click on the segue that you created (either in the Document Outline or directly on the storyboard).
In the Utilities bar (right-side pane), go to the Attributes Inspector. There you will see Identifier of the Storyboard Segue. Make sure that it is the correct value.
Third, make sure that your custom table view cell has User Interaction Enabled checked.
In your storyboard, click on your custom cell.
Go to the Attributes Inspector. Look for the Interaction field within the View section. Make sure that it is checked.