How to get textLabel of selected row in swift?
Asked Answered
L

8

42

So i am trying to get the value of the textLabel of the row I select. I tried printing it, but it didn't work. After some research I found out that this code worked, but only in Objective-C;

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath    *)indexPath
    {
        NSLog(@"did select  and the text is %@",[tableView cellForRowAtIndexPath:indexPath].textLabel.text);]
    }

I could not find any solution for Swift. Printing the indexpath.row is possible though, but that is not what I need.

so what should I do? or what is the 'Swift-version' of this code?

Langham answered 2/10, 2014 at 10:17 Comment(0)
L
142

Try this:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let indexPath = tableView.indexPathForSelectedRow() //optional, to get from any UIButton for example

    let currentCell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell

    print(currentCell.textLabel!.text)
Lied answered 2/10, 2014 at 10:36 Comment(4)
This worked for me! the only thing I had to change was putting an ! after indexPath and UITableViewCell. thank you so much!Langham
what's different between the to indexPath from params and get by tableView.indexPathForSelectedRow() ?Maecenas
Its the same. It should just show you a method where to get your current selected indexPath too. Maybe from any Button in a View.Lied
Swift 4.1 let indexPath = tableView.indexPathForSelectedRow let cell = tableView.cellForRow(at: indexPath!)Lourielouse
S
15

If you're in a class inherited from UITableViewController, then this is the swift version:

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = self.tableView.cellForRowAtIndexPath(indexPath)
    NSLog("did select and the text is \(cell?.textLabel?.text)")
}

Note that cell is an optional, so it must be unwrapped - and the same for textLabel. If any of the 2 is nil (unlikely to happen, because the method is called with a valid index path), if you want to be sure that a valid value is printed, then you should check that both cell and textLabel are both not nil:

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = self.tableView.cellForRowAtIndexPath(indexPath)
    let text = cell?.textLabel?.text
    if let text = text {
        NSLog("did select and the text is \(text)")
    }
}
Sycophant answered 2/10, 2014 at 10:37 Comment(2)
hi, I am not using an TableViewController, just a tableview inside a ViewController. this works fine for me until this point.. When I paste your code in the ViewController-class, it gets an error which says method does not override any method from its superclass. this is fixed by deleting the override-section. When I tried running the code again, it says (UITableView, numberOfRowsInSection: Int) -> int' does not have a member named 'cellForRowAtIndexPath'. what can I do to fix this??Langham
You probably have to make the view controller implement the UITableViewDelegate protocol, and set the delegate property of the table view to self - viewDidLoad is a good placeSycophant
V
11

Swift 4

To get the label of the selected row:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
    print(cell.textLabel?.text)
}

To get the label of the deselected row:

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
    print(cell.textLabel?.text)
}
Vere answered 2/5, 2017 at 13:38 Comment(0)
E
4

If you want to print the text of a UITableViewCell according to its matching NSIndexPath, you have to use UITableViewDelegate's tableView:didSelectRowAtIndexPath: method and get a reference of the selected UITableViewCell with UITableView's cellForRowAtIndexPath: method.

For example:

import UIKit

class TableViewController: UITableViewController {

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 4
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

        switch indexPath.row {
        case 0: cell.textLabel?.text = "Bike"
        case 1: cell.textLabel?.text = "Car"
        case 2: cell.textLabel?.text = "Ball"
        default: cell.textLabel?.text = "Boat"
        }

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let selectedCell = tableView.cellForRowAtIndexPath(indexPath)
        print(selectedCell?.textLabel?.text)
        // this will print Optional("Bike") if indexPath.row == 0
    }

}

However, for many reasons, I would not encourage you to use the previous code. Your UITableViewCell should only be responsible for displaying some content given by a model. In most cases, what you want is to print the content of your model (could be an Array of String) according to a NSIndexPath. By doing things like this, you will separate each element's responsibilities.

Thereby, this is what I would recommend:

import UIKit

class TableViewController: UITableViewController {

    let toysArray = ["Bike", "Car", "Ball", "Boat"]

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return toysArray.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
        cell.textLabel?.text = toysArray[indexPath.row]
        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let toy = toysArray[indexPath.row]
        print(toy)
        // this will print "Bike" if indexPath.row == 0
    }

}

As you can see, with this code, you don't have to deal with optionals and don't even need to get a reference of the matching UITableViewCell inside tableView:didSelectRowAtIndexPath: in order to print the desired text.

Enfranchise answered 29/11, 2015 at 6:47 Comment(0)
G
4

In my case I made small changes, when i search the value in tabelview select (didSelectRowAtIndexPath) the cell its return the index of the cell so im get problem in move one viewControler to another.By using this method i found a solution to redirect to a new viewControler

let indexPath = tableView.indexPathForSelectedRow!
let currentCellValue = tableView.cellForRow(at: indexPath!)! as UITableViewCell
let textLabelText = currentCellValue.textLabel!.text
print(textLabelText) 
Gotham answered 8/8, 2016 at 7:26 Comment(0)
K
3

In swift 4 : by overriding method

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let storyboard = UIStoryboard(name : "Main", bundle: nil)
        let next vc = storyboard.instantiateViewController(withIdentifier: "nextvcIdentifier") as! NextViewController

       self.navigationController?.pushViewController(prayerVC, animated: true)
}
Kilogrammeter answered 25/7, 2018 at 12:49 Comment(0)
I
1

This will work:

let item = tableView.cellForRowAtIndexPath(indexPath)!.textLabel!.text!
Inventive answered 7/8, 2015 at 19:14 Comment(1)
While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.Hollington
M
0

Maintain an array which stores data in the cellforindexPath method itself :-

[arryname objectAtIndex:indexPath.row];

Using same code in the didselectaAtIndexPath method too.. Good luck :)

Michaelis answered 22/3, 2015 at 17:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.