I have a main TableViewController. When the user tap on a cell in TableView, If a condition statement is true, show the main TableViewController again(but show another data on screen), and if the condition is false, show another ViewController.
In the prepareForSegue method I have this:
if segue.identifier == "identifier1"
{
let destination = segue.destinationViewController as? mainViewController // itself
destination!.x = something // the x variable is in this view controller
}
else if segue.identifier == "identifier2"
{
let destination = segue.destinationViewController as? viewController2
destination!.y = something
}
Also, to run segue after tap on cells in tableView I added this:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
if condition is true {
self.performSegueWithIdentifier("identifier1", sender: self)
}
else{
self.performSegueWithIdentifier("identifier2", sender: self)
}
}
Storyboard segue needs an identifier... It can just have one value! identifier1 or identifier2
But I want to set the identifier programmatically.
How should I set the identifier in Storyboard segue?
Is there another way to do this?
Thanks!
The destination view controller is set by the segue. Since you have two different destinations, you need two different segues in your Storyboard.
The trick is to wire the segues from the viewController icon at the top of tableViewController to each of the destination view controllers. Click on the resulting segue arrows and set their identifiers in the Attributes Inspector.
Then you can call them with performSegueWithIdentifier as you have done in your code.
Don't invoke a segue directly from the cell tap. Use an IBAction method (probably in `didSelectRowAtIndexPath, like you show in the second block of code.
That second block of code DOES set the segue identifier programmatically.
You can't switch segues in prepareForSegue.
Related
I am very new to Swift, and i'm wondering how to perform segue when user tap one of the table view cells.
In UITableViewCell controller I tried to type performSegue and wait for hints by Xcode like below
override func setSelected(_ selected: Bool, animated: Bool) {
if selected {
performSegue() <- HERE
}
super.setSelected(selected, animated: true)
}
I couldn't find any hints, so I think i misunderstand the concept.
Is there any way to perform segue when a cell is tapped? And I also want to send some data to the destination, so it'll be great if you can provide a way to send data to the destination as well.
Thank you in advance.
Segues In Code:
So firstly a good way of performing something when a cell (table view cell) is tapped is using the tableView didSelectRowAt method:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Place code you want to be performed when a cell is tapped inside of here, for example:
performSegue(withIdentifier: "identifier", sender Any?) // Make sure your identifier makes sense and is preferably something memorable and easily recognisable.
}
The segue identifier is just so that swift/interface builder knows which segue you are referring to.
The sender is the thing which caused the segue to be performed an example of this is a UIButton.
Next you will need to prepare for the segue inside of the View Controller which is being segued to using the following method:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Do any required setup for this segue such as passing in data loading required views and specifying how you want the segue to be performed such as if you want the view to be pushed, or presented as a popover etc... for example:
if let vc = segue.destination as? ViewController { // Downcast to the desired view controller.
// Configure the view controller here...
}
}
NOTE: You can also create segues in interface builder by control dragging from something such as a UIButton and then setting the segue identifier in the Attributes Inspector in the panel on the right:
Segues In Interface Builder:
Control drag and this menu will pop up for you to select the presentation:
Then set an identifier for the segue in the Attributes panel in the right side of the screen:
Finally prepare for the segue inside of the view controller which will be segued to in code just like you do when creating a segue in code.
This video might also be useful to you to gain more clarification on segues and how to perform and prepare for them etc:
https://youtu.be/DxCydBmOqXU
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.
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 am sorry for echoing same question but after a lot of time spending I could not figure out the issue.
Suppose, a UITableView have 2 table_cell s and I want to navigate different UIViewController from each table_cell. How do I do that?
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == 0 {
// go to DetailVC_1
} else if indexPath.row == 1 {
// go to DetailVC_2
}
Either present a new view controller manually:
self.presentViewController(controller, animated:true, completion:nil)
// or push on a navigation controller
self.navigationController.pushViewController(controller, animated:true)
Or perform a segue you set up in a storyboard earlier. (Drag from the view controller to another view controller in your storyboard).
self.performSegueWithIdentifier("MyIdentifier", sender: self)
When using storyboards you can also use multiple cell types and setup a segue from each cell type to a new controller. This way the new controller will be presented automatically. The only code you might need to use in that case would be a prepareForSegue method where you pass the correct information to the presented controller before the segue is performed.
Try this:
if indexPath.row == 0 {
self.performSegueWithIdentifier("firstViewController", sender: self)
} else if indexPath.row == 1 {
self.performSegueWithIdentifier("secondViewController", sender: self)
}
If you have several view controllers, you can call them viewController0 and viewController1 etc. Then you can have a string "viewController" + String(indexPath.row). Hope this helps.
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.