Stormios
Stormios

Reputation: 127

Get textLabel from UITableView

I need to get textLabel from row in UITableView. But I get nil. I need to get textLabel, because I'm using UISearchBar, if I will try to get data using index, when searching, I will receive incorrect indexes. So , I want to get textLabel. Please, fix where I'm wrong

When I am typing in searchBar items in TableView change. But index doesn't. For example Food = ["Apple", "Banana", "Coca-Cola"]. If I use searchBar and enter "Banana". Then I click on this , but I get Apple (because this is index - 0). That's why I want to get textLabel

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        //let meal = foods[indexPath.item]
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let labelContent = cell.textLabel!.text
        print(labelContent)
    }

UISearchBar

extension FoodViewController: UISearchBarDelegate {

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    searchedFoods = foods.filter({ $0.title.lowercased().prefix(searchText.count) == searchText.lowercased() })
    searching = true
    tableView.reloadData()
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searching = false
    searchBar.text = ""
    tableView.reloadData()
  }

}

Upvotes: 1

Views: 77

Answers (6)

Neeraj
Neeraj

Reputation: 91

As I have figured out the problem is that you are using indexPath.item that's why you are getting the wrong index please try this

let meal = foods[indexPath.row]

Upvotes: 1

Neeraj
Neeraj

Reputation: 91

Try This

extension FoodViewController: UITableViewDataSource {

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    if searching {
        let food = searchedFoods[indexPath.row]
        cell.textLabel?.text = food.title
    } else {
        let food = foods[indexPath.row]
        cell.textLabel?.text = food.title
    }
    return cell


}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if searching {
        return searchedFoods.count
    } else {
        return foods.count
    }
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

if searching {

         let meal = searchedFoods[indexPath.row]
    let labelContent = meal
    print(labelContent)
    } else {
         let meal = foods[indexPath.row]
    let labelContent = meal
    print(labelContent)
    }

}

Upvotes: 0

Saravanan B
Saravanan B

Reputation: 59

Please try like this,

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if searching {
            print(searchedFoods[indexPath.row])
        } else {
            print(foods[indexPath.row])
        }
    }

Upvotes: 0

vadian
vadian

Reputation: 285059

Never get data from the view, the cell, get it always from the model, the data source.

And never use dequeueReusableCell outside of cellForRowAt. You won't get the cell you expect.

In this case you have to get the data depending on searching

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let labelContent : String
    if searching { 
       labelContent = searchedFoods[indexPath.row].title
    } else {
       labelContent = foods[indexPath.row].title
    }
    print(labelContent)
}

And your filter method is horrible. Change it to much more efficient

searchedFoods = foods.filter { $0.title.range(of: searchText, options: [.caseInsensitive, .anchored] != nil) }

Finally I recommend to change textDidChange to cancel searching also if the search text becomes empty and remove the unused items from searchedFoods.

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchText.isEmpty {
        searchedFoods.removeAll()
        searching = false
    } else {
        searchedFoods = foods.filter{ $0.title.range(of: searchText, options: [.caseInsensitive, .anchored]) != nil }
        searching = true
    }
    tableView.reloadData()
}

Upvotes: 3

ManuRaphy
ManuRaphy

Reputation: 391

Lets just say instead of getting data from foods (in didSelect method) get it from searched Food. But for that to work properly you should assign searched food with food initially and also when the user clears search bar you should again reset searched food to food data.

Upvotes: 0

channu
channu

Reputation: 298

If you want to get a text from the UILabel on tap of cell

confirm UITableViewDelegate

//Access the array that you have used to fill the tableViewCell
    print(foods[indexPath.row]) it will print selected row 
OR

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

Upvotes: 0

Related Questions