简体   繁体   中英

Pass information from a tableview to a view controller based not on indexPathForSelectedRow, but on label text of cell selected?

I have a tableview inside of a UIViewController , and on Main.storyboard , I have a show segue from the prototype cell on the tableview in the first view controller to the second view controller . I have this code:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showTheSeriesPage"
    {
        let indexPath : NSIndexPath = self.theTableAyy.indexPathForSelectedRow! as NSIndexPath
        var destViewController = segue.destination as! SeriesPageViewController
        var randomTemporaryArray = dataAry[indexPath.row]

        destViewController.sampleTitle = randomTemporaryArray.objectSeriesTitle
        destViewController.sampleAuthor = randomTemporaryArray.objectSeriesAuthor
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}

It works, but only when the the tableview is in a specific order and is based on the indexPath.row , not on the specific details of the cell itself. How do I set it so that it doesn't depend on the indexPath.row selected, but maybe the label text of the cell? Thanks!

Short answer: Don't do that. Your current approach is the correct one. You should have a data model that contains the information displayed in your table view. When the user taps a cell, you should use the indexPath of the selected cell to look up the entry in your model, and then fetch whatever string is appropriate for that entry.

Cells are view objects and you should not use them to store information.

I understand this problem as this is common when you link the TableView with the search button. Especially, if you have a search bar linked to table results to change dynamically.

I saw many posts using the prepareForSegue function but I wanted to use prepare function to segue to next view like you. In my case, to have a more controlled code area that sends the segue in action from a single contained function.

my solution: 1. I had to declare 2 variables in your view controller to store the filtered results (dynamic new list in table view) and the selected row. for example if we were dealing with car listings then,

var filteredCars = [Car]()
var selectedCar: AnyObject!

then in the searchBar function:

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    filteredCars = self.cars.filter({ (x: Car) -> Bool in

        return x.name?.lowercased().range(of: searchText.lowercased()) != nil

    })

    self.tbvOriginalTable.reloadData()
    // IMPORTANT store the new filtered table results to use them later
    saveFilteredTable = self.tbvOriginalTable

}

now in the prepare function:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "optionlist" {

        let controller = segue.destination as! MealListTableViewController
        // this is the declared @IBOutlet weak var searchCar: UISearchBar!
        if searchCar.text != "" {
controller.car = filteredCars[(saveFilteredTable.indexPathForSelectedRow?.row)!]

        } else {
            controller.car = cars[(tbvOriginalTable.indexPathForSelectedRow?.row)!]
        }
    }
}
// We have to use the controller to assign an object of type car on the other side of the segue to receive the passed record

This really did the trick for me, it took me a bit of reading and research and finally got it done without needing to use func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) coupled with prepareForSegue function or any other type of long coding

I hope this is useful to many people as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM