How to know which cell was tapped in tableView using Swift - swift

I am using a tableView to display a list of names. When the user taps on one of the cells, a popup should come up showing more detail. I am using this function to check what cell the user has tapped.
var selectedCell: Int?
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("This cell from the chat list was selected: \(indexPath.row)")
selectedCell = indexPath.row
}
Unfortunately, it seems to give give back random numbers between 0 and 2 (I currently have three cells that are displayed).
Do you know how I could know which cell was tapped?
Thank you in advance.
EDIT:
I understood what is falsing my results.
I am using this function to push which cell is selected to another view controller (named ConversationViewcontroller). But, the segue fonction is called before the tableView function, and so the segue pushes the previously selected cell. How could I correct this?
Here is the code for my segue:
//SEGUE: Cell was selected: pass chatID
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "OpenChat" {
if let toViewController = segue.destination as? ConversationViewController {
toViewController.chatIdentifier = selectedCell
}
}
}
Thanks again.

try this
var selectedCell: IndexPath
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("This cell from the chat list was selected: \(indexPath.row)")
selectedCell = indexPath
}
if you want use IndexPath
self.selectedCell?.row

Related

Im trying to perform a segue but cant grab the selected cell info with an IBaction and cellForRowAt is not registering

I'm trying to perform a segue and want to use the text of the selected cell to control what information is displayed on the new screen. I can use the IBaction to perform the segue but as yet can't figure out how to grab the cell info. So I then tried using
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) and didselectrowat but neither are working. I have tried removing the IBaction and deleting the button which gets rid of the Invalid argument NSexception fault but when I click on the cell absolutely nothing.
Ive included my code and in its current form the segue does happen albeit with no info displayed . If I delete the IBaction line and remove the button from the storyboard then nothing. Please point me in the right direction.
// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
#IBAction func segueToDriverRDWList(_ sender: UIButton) {
print("SEGUE")
performSegue(withIdentifier: "gotodriverRDWlist", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! DriverRDWViewController
// destinationVC.selectedDriver = driverNameArray[indexPath.row]
// print(driverNameArray[indexPath.row])
}
As per my knowledge you haven't confirmed datasource and delegate method of UItableview, that's why didselect method were not working. Please refer this for more details
https://shrikar.com/uitableview-delegate-and-datasource-in-swift/#:~:text=Create%20a%20new%20file%20called%20MainViewController.,the%20UITableViewDataSource%20and%20UITableViewDelegate%20Protocol.&text=numberOfRowsInSection%20will%20tell%20how%20many,tableview%20for%20that%20particular%20section.
You don't need an #IBAction, just use the didSelectRowAt, and your class must conform to the UITableViewDelegate & UITableViewDataSource protocols (dataSource and delegate must be set as self as well) :
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "gotodriverRDWlist" {
let destinationVC = segue.destination as! DriverRDWViewController
//Pass your data here
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "gotodriverRDWlist", sender: nil)
}

How to make a push segue when a specific UITableViewCell is selected

I am working on my first iOS app and new student to swift.
Everything is working however I am having trouble figuring out how to segue from a specific cell to a third view controller. I have a IOS UITableView with three sections and a total of (44) cells. All cells when tapped segue to one DetailVC titled: showProductDetai which is fine. The problem that I am having is that I need to have only (1) particular cell in section 0 row 5 in the UITableView to go to its own ViewController in which I titled: second view controller instead of the normal showProductDetail VC. Is there an intelligent way to make the specific cell in section 0 row 5 of the tableView go to second view controller when selected?
Here is my current code that is working. How would I code to make the changes?
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell", for: indexPath) as! ProductTableViewCell
// Configure the cell...
let productLine = productLines[indexPath.section]
let products = productLine.products
let product = products[indexPath.row]
cell.product = product
return cell
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let productLine = productLines[section]
return productLine.name
}
// Mark: UITableViewDelegate
var selectedProduct: Product?
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let productLine = productLines[indexPath.section]
let product = productLine.products[indexPath.row]
selectedProduct = product
performSegue(withIdentifier: "ShowProductDetail", sender: nil)
}
// Mark: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "ShowProductDetail" {
let DetailVC = segue.destination as! DetailViewController
DetailVC.product = selectedProduct
}
}
see what I did here? You can use the indexPath parameter to get the section & row the user touched, and then you can set up your programmatic segue.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if ((indexPath.section == 0) && (indexPath.row == 5)) {
performSegue(withIdentifier: "GoToSecondViewController", sender: nil)
} else {
let productLine = productLines[indexPath.section]
let product = productLine.products[indexPath.row]
selectedProduct = product
performSegue(withIdentifier: "ShowProductDetail", sender: nil)
}
}
Write a segue code for the desired section and row:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 && indexPath.row == 5 {
//Perform Segue
} else {
//Rest of the functionality
}
}
Make sure you have connected proper Sugues and given proper identifiers in Storyboard.
You don't need to write prepare Segue method

UITableView - Execute a different function in primary view controller, based on row number of UITableView

Using the following code to create my UITableView which works well:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return(arrayOfImages.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ViewController2TableViewCell
cell.niceImage.image = UIImage(named: arrayOfImages[indexPath.row] + ".png")
return(cell)
}
Then, I am using the following code to unwind segue onto ViewController1 and execute my function, which also works well:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destVC = segue.destination as! ViewController
destVC.posn += 1
destVC.myFunction(Parameter1: 1)
arrayOfImages contains 10 images (for now). I want each image (aka each row in my UITableView) to execute a different function in destVC. I.e the function is dependant on row number. Using the above code, the same function is executed on every row, which is not ideal
I tried utilising the following:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
myIndex = indexPath.row
}
And then making my function dependant on indexPath.row's value, but myIndex always came up as 0, regardless of what row it actually was
You send integer 1 for your destVC function's parameter everytime. Thats the problem. Send the selected indexPath.row of tableView in prepareForSegue method
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let indexPath = tableView.indexPathForSelectedRow {
let destVC = segue.destination as! ViewController
destVC.posn += 1
destVC.myFunction(Parameter1: indexPath.row)
}
}

How to create segue from Detail disclosure of static cell from xib file

Have some question that I can't figure out. I have single static cell in xib file and I want to make segue from detail disclosure accessory of that cell to other view controller.
Guess that I have to use this method:
func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
self.performSegue(withIdentifier: "SegueID", sender: self) // #ERROR
}
But I have an error:
Could not cast value of type 'Lists.ListViewController'
(0x104c0e7b8) to 'UITableViewCell' (0x106875bf8).
How can I create this segue correctly?
If you want to access the cell in prepareForSegue you can try like this way.
func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
//Pass the indexPath as sender
self.performSegue(withIdentifier: "SegueID", sender: indexPath)
}
Now access that indexPath in prepareForSegue.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SegueID" {
let nextVC = segue.destination as! DestinationVC
if let indexPath = sender as? IndexPath,
let cell = self.tableView.cellForRow(at:indexPath) as? CustomCell {
//access your cell here
}
}
}

Custom UITableViewCells repeating when navigating to viewcontroller

I am making a running app, and would like the user to see the races/marathons in their city. When clicking on the cell the user is navigated to a new view controller with details of the marathon. But upon pressing the back button to go back to the table the cells repeat. for example, if scrolling on the table it will display cell 1, cell 2,cell 3, cell 4,cell 1, cell 2,cell 3, cell 4 and will repeat more every time I navigate to the view controller with the table.
The code for the table is:
//MARK: TableView
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return exhibitions.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let singleCell: marathonTableViewCell = tableView.dequeueReusableCellWithIdentifier("marathonCell") as! marathonTableViewCell
singleCell.marathonName.text = exhibitions[indexPath.row]
singleCell.entryNumber.text = "\(entryNumber[indexPath.row])"
singleCell.entries.text = "\(entires[indexPath.row])"
return singleCell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("marathonDetail", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "marathonCardDetail"){
var upcoming: marathonDetailViewController = segue.destinationViewController as! marathonDetailViewController
let indexPath = self.marathonsTableView.indexPathForSelectedRow!
let currentCell = marathonsTableView.cellForRowAtIndexPath(indexPath) as! marathonTableViewCell
let marathonEvents = currentCell.marathonName.text
upcoming.nameMarathon = marathonEvents
self.marathonsTableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
I am using swift, Xcode 7, and Parse as my backend.
I think u have to init ur array before update tableview.
When u click back button, tableview may refresh.
So make some code that makes ur array new, and then call tableview.reloadData()