Swift DidSelectRowAt not firing - swift

I have a project with a few different VCs...two of them have TableViews
The first one works perfectly fine, I have a custom view in there etc.
The second one is also custom and it fill the information in just fine, but unlike the first one...I cannot tap on it to segue to the next VC
I have the Delegate and DataSource set up properly. I have another VC on my project with a tableview and it works just fine. The first thing I can think might be preventing it from working is a UILabel takes up 90% of the cell, but I don't think that is it because I made the label small and tried tapping then and it still wouldn't hit the breakpoint.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let row = indexPath.row
selectedService = serviceArray[row].serviceID! as String
if selectedService != "" {
self.performSegue(withIdentifier: "fromCardDetailsToEditService", sender: self)
}
}
I do not know if it matters BUT...the VC that I am on is in a Tab Bar Controller and a Nav Bar Controller. Does it matter for the performSegue that I am in a Tab Bar? And that this button is not a tab bar item?

Did you have any GestureRecognizer on your UIViewController because in case of GestureRecognizer tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) does not called.

I figured out how to have my Gesture Recognizer AND the didSelectRowAt.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(CardDetailsViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
This is what I already had, which was causing conflict.
To fix it, this simple line let me dismiss the keyboard AND be able to tap on my cells.
tap.cancelsTouchesInView = false

Related

How to transfer data from one tableViewCell to another tableViewCell in swift

How i can transfer data from cell of tableView to cell of another tableView. I am confused about it. I can try delegate method,closure but they doesn't work on it. I want to show data of cell to cell of another tableView by single click on button. So please help me.
I try closure and delegate method to transfer data .but it doesn't work.Actually i am confused in tableView didSelectRowat function. It deal with cell on which i tapped and next step is when i tap on button this cell data shown on another cell which has different tableView & different viewController.
Assuming first tableviewcontroller is called "ItemsViewController"
and your second view controller is called "DetailViewController"
in your ItemsViewController add this to your didSelectRowAt delegate function:
then you can send that cells information to the next view according to it's IndexPath
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController {
vc.image = UIImage(named: images[indexPath.row])
vc.name = names[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
}
}

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

Swift - Clicked button inside tableview cell does not call the did select row at function of that cell

I creating a tableview programatically and each tableview cell have buttons associated to them.
If I click the row I can work out the tag associated with the buttons on that row and then able to edit the title when applying some other functions.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
TmpActionConnectorTag = indexPath.row + 700 //Tag associated to button
}
When the button is clicked , I have this code which changes the other button on that row
let tag = TmpActionConnectorTag
let tmpButton = self.view.viewWithTag(tag) as? UIButton
The issue is if I directly click on the button in the tableview cell, the did select row does not get call and no tag value is given. To do it I have to click within the cell first and then the button to be able to know the tag associated with the row.
Is there a way to workout the index row when the button is clicked so I don't have to click the actual cell?
above is how the cell looks normally and below shows how the cell has to be selected to be able to get the index value.
Button action won't call the didSelectRowAt. You should go for delegate method. If not aware about delegate means refer this
The cell's button will not trigger func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) instead you need to add a target to your button which is typically done within cellForItemAt.
Add target to button within cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = MyTableViewCell()
cell.button.tag = indexPath.row
cell.button.addTarget(self, action: #selector(didTapCellButton(sender:)), for: .touchUpInside)
}
Handle button action
#objc func didTapCellButton(sender: UIButton) {
guard viewModels.indices.contains(sender.tag) else { return } // check element exist in tableview datasource
//Configure selected button or update model
}
Disabling the button's control worked for me.
Programmatically:
editButton.isEnabled = false
~OR~
IB:
Uncheck the Enabled box in the Control section.

didSelectCellAtIndexPath not called

I know there are a lot of relevant post on this and I have tried all of the ones I can find and unfortunately the problem still persists.
So I have a tableView inside of an UIViewController which is populated by 2 custom cells, one has got an UITextField and the other one got an UISwitch, and both have a UILabel. I then proceeded to implement the didSelectCell(at: IndexPath) method
I made sure the delegate is hooked up to the view controller.
Inside of the method, I simply wrote a print statement to ensure the taps are registering. However, the print message did to get printed to the console when I tapped on the UITextField and on the UILabel.
I have a feeling it is something to do with the firstResponder thing with the UITextField, and it is eating away my tap registration, but not really sure.
Any feedbacks are welcome!
UPDATE
Here is the setup on my custom cell:
Here is the didSelect method:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("tapped on cell")
if let cell = tableView.cellForRow(at: indexPath) as? NumericInputTableViewCell{
print("Tapped on numericcell")
} else if let cell = tableView.cellForRow(at: indexPath) as? BooleanInputTableViewCell {
print("Tapped on booleancell")
}
}
The delegate method is triggered when you click on the cell, not other elements on the cell. So create some empty cell in your table view and have another try. If it get printed out then that means you have elements covered over the cell and the cell itself is not clicked.
You can then disable user interaction for your UITextField stuffs from storyboard and then have a try. Ideally, when you click on the textfield on a table view cell, the correct respond I am thinking is that keyboard will show up and didSelectCell should not be triggered.
Here is the demo

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