How to perform a segue from TableView programmatically - swift

I have a TableView on a ViewController and want to segue to another ViewController by pressing any row. My Code for this is:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "ShowDetailView", sender: Cell)
}
I have connected both ViewControllers in the storyboard and named the storyboard segue identifier "ShowDetailView", but i get an error with this code?
Can somebody give me an advise?

It seems that you need to send clicked cell for getting the content , so replace
performSegue(withIdentifier: "ShowDetailView", sender: Cell)
with
performSegue(withIdentifier: "ShowDetailView", sender:arr[indexPath.row])
Where arr is the table's dataSource array , if you don't need to send anything do
performSegue(withIdentifier: "ShowDetailView", sender:nil)

Its because in the destination, “detailsViewController” there was a subView called ‘itemLabel’ that you either delete or rename it in code and forgot to disconnect its outlet from UI. Right click on it and hit X on itemLabel outlet

Related

I want to prevent a navigation controller segue from happening when a row is tapped, but do want to segue when the accessory button is tapped

I'm getting an unwanted segue when I tap a tableview cell. I only want to do the segue when the accessory button is tapped. The current code works when I tap the accessory button on a cell. But if I tap the content view, a segue happens and my prepare(for:sender:) fails because sender isn't an IndexPath, it's an TableViewCell. BTW, the view containing the TableView is on a navigation controller stack.
I tried deselecting User Interaction Enabled setting for the content view of the table view cell, but that seems to inhibit the accessory button also.
This works as expected
func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
performSegue(withIdentifier: "ShowDetails", sender: indexPath)
}
When the cell is tapped, this is getting called before the prepare(for:sender:) is called.
func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
log.debug("didHightlightRowAt")/
}
I don't know how to prevent the segue when the cell is tapped. When the cell calls the prepare(for:sender:), I get this error:
Could not cast value of type 'UITableViewCell' (0x11edbdaa0) to 'NSIndexPath' (0x10e209cf8).
2019-06-06 12:10:24.086845-0500 Earthquakers[1668:53901] Could not cast value of type 'UITableViewCell' (0x11edbdaa0) to 'NSIndexPath' (0x10e209cf8).
when this code executes:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.destination is DetailViewController {
let indexPath = sender as! IndexPath
(because sender is a tableviewcell)

Swift segue negating other functions connected to segue object

In a table view controller, I'm trying to get the index of the row that is selected before I segue (will pass this info in prepare for segue eventually). I have implemented this function:
var selectedQuestionCell: IndexPath?
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedQuestionCell = indexPath
}
This was working great for me initially. I was able to snag the index of the selected row in my table. However, I want to perform a segue when a row is tapped which will transfer to another View. I connected a segue to my cell (dynamic prototypes). After connecting a segue, my override function no longer executes! I'm really new to Table View Controllers, so I'm not sure if there's anyway I can manually execute this.
To summarize: my problem is after connecting a segue to my cells, the override function to get their index is no longer called. How can I fix this?
Try these thing
Create a new segue from your tableview to another view and name it as you like.
Now add this code inside your didSelectRowAt
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let viewController = storyboard?.instantiateViewController(withIdentifier: "your_segue_name_here") as! YourViewControllerName
self.navigationController?.pushViewController(viewController, animated: true)
}
Please make sure that your tableview is connected with navigation controller.
To do that select your tableView then click on Editor -> Embed In -> Navigation Controller from your Xcode.
I hope it works for you.
: D

Navigate to a new view controller for every cell in table view

I am a beginner coder in swift. I am trying to create a tabbed application. For one of my tabs, I am creating a table view which has multiple rows each which have a different task (A good way to think of this is the facebook app, where each option in the more screen will take you to a separate view)
Now, my table is populated with an array:
let array = ["one", "two", "three]
I want to ask, that everytime that I tap on one of these rows, I would like to go a new view controller. How is this possible?
What I tried was performSegue with an identifier which I give in the storyboard, but then there would be an x amount of segues connecting to the table view? So I don't think this is right? :/
I know the contents of the array prior to generating the table, so If I know the array value, and the row being tapped, how can I navigate to a new view controller?
Edit:
When performing the segue between the controllers, I am using:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "showView", sender: self)
}
This of course will only connect to the segue showView however, how can i add multiple view controllers?
You need to simply compare which row is selected in tableView and then perform segue according to it.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let segueIdentifier: String
switch indexPath.row {
case 0: //For "one"
segueIdentifier = "showView1"
case 1: //For "two"
segueIdentifier = "showView2"
default: //For "three"
segueIdentifier = "showView3"
}
self.performSegue(withIdentifier: segueIdentifier, sender: self)
}
Add the following function to your controller.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
navigationController?.pushViewController(NewController(), animated: true)
}
Using Static Cells in a UITableViewController
Summary
An alternative is to use a UITableViewController with static cells. If you know already know the menu then you can just create static cells for each item.
In the storyboard you can connect a segue from each cell to their respective view controllers.
Example

Storyboard TableView with Segues to Multiple Views

I am having an issue with designing a storyboard. I currently have an app in the app store that was designed with XIB files. I have a tableView placed on a UIViewController - not a tableViewController - that loads a unique viewController for each row that is selected.
I am trying to convert this concept to a storyboard. I've done the following
Place a UIViewController in the Storyboard.
Place a UITableView on the UIViewController so I can customize the table view.
I tried making connections to multiple ViewControllers from the UITableViewCell and I am not allowed.
I tried creating multiple segues from the UIViewController - which I can - but when I click on the cells the segues are not fired. I tried using didSelectRowAtIndexPath: and prepareForSegue:
Since this did not work I tried creating a project with a UITableViewController and then created multiple segues from the UITableViewController. I then named each segue and used the didSelectRowAtIndexPath: method to test the selected cell and called performSegueWithIdentifier: and this did not work. As I clicked on cells I would get random loading of the incorrect viewController. I've copied a bit of my code and few screen shots below.
I am wondering if I am blatantly missing something obvious or do I have to revert to a xib format for this type of project?
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
{
if indexPath.row == 0
{
println("Segue1")
self.performSegueWithIdentifier("Segue1", sender: self)
}
else if indexPath.row == 1
{
println("Segue2")
self.performSegueWithIdentifier("Segue2", sender: self)
}
else if indexPath.row == 2
{
println("Segue3")
self.performSegueWithIdentifier("Segue3", sender: self)
}
}
Take care,
Jon
The method
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) is called when an item is deselected.
To call a method when an item is selected, change the method name to override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
I used a combination of the comment by Allen. Initially I wasn't able to create the segues I needed. I created a navigation controller that uses my own view controller that holds a tableview. Then I created the associated cells for the prototype cells and switched them to a static cell. I only have a limited amount, 3 at the time. This allowed me to created the segues to the appropriate views in the storyboard. Then I changed the cells back to prototype cells and it maintained the connection to the segues. All that is left was creating the associated switch statement in the table view to go to the correct segue. Just make sure you name your segues with the identifiers listed in your code.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath) {
//Add cases here to move to different segues
switch indexPath.row{
case 0: self.performSegueWithIdentifier("courses", sender: self);
break;
case 1: self.performSegueWithIdentifier("finals", sender: self);
break;
case 2: self.performSegueWithIdentifier("academic", sender: self);
break;
default:
break
}
}
Swift 3 Code
Well, look at my piece of code I use to perform dynamic segue based on the type of the device type in the cell. :) Hope it helps.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let device = Cache.DEVICELIST[indexPath.row]
let deviceType = device.type
switch deviceType {
case "camera":
self.performSegue(withIdentifier: "DashCellToCamera", sender: self)
case "gateway" :
self.performSegue(withIdentifier: "DashCellToGateway", sender: self)
case "tracker" :
self.performSegue(withIdentifier: "DashCellToTracker", sender: self)
case "panicbutton" :
self.performSegue(withIdentifier: "DashCellToPanicButton", sender: self)
default:
break
//do nothing just ignore this
}
}

Swift - Segue from Button inside a cell

i have a custom cell attached to TableViewCell class, and i have a button inside that custom cell, i want whey i press the button it segues to another view controller, but the:
performSegueWithIdentifier(identifier: String, sender: AnyObject?)
function is not recognised, how to fix that ?
Edit:
-performSegueWithIdentifier: method is declared in UIViewController. So you can't just call it in UITableViewCell subclass.
You can add an action to that button when you are creating cell in -tableView:cellForRowAtIndexpath: method. Then you can call -performSegueWithIdentifier: method in that action method. Here is example assuming we are in UITableViewController subclass:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.button.addTarget(self, action: "someAction", forControlEvents: .TouchUpInside)
return cell
}
And here is action method:
func someAction() {
self.performSegueWithIdentifier("moveToView", sender: self)
}
You need a custom class for your cell. In that class, create an #IBAction as response to the button click. In that action, perform your segue.
If you are using Interface Builder:
Connect your firstViewController to the secondViewController - and create a Segue Identifier.
Then you are able to use
performSegueWithIdentifier(identifier: String, sender: AnyObject?)