L. Hinton
L. Hinton

Reputation: 79

Segue to tableview from a tableview but display different data for the tableview depending on which cell is selected

Is it possible to present different data to the same table view depending on which cell of the previous table view is selected?

enter image description here

For example, the first table view above will already be populated with data, I then want the cells to link to the other table view which should contain items in each cell. At the moment I can only get it to show the same data in the table.

So how would I show the different data within the same table view and present the different data when different cells are selected from the previous view controller? The data is been saved and pulled from core data in the form of an array.

Is this possible or will I need to create different table views ready to be populated by the user?

Here is the code for the first TableViewController:

import UIKit

class ListsViewController: UITableViewController {
    
    let viewController = ListNameViewController()
    let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext
    
    override func viewDidLoad() {
        super.viewDidLoad()
        viewDidAppear(false)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(false)
        viewController.loadList()
        self.tableView.reloadData()
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewController.listName.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell3", for: indexPath)
        let result = viewController.listName[indexPath.row]
        cell.textLabel?.text = ("\(String(result.listName!))")
    
        return cell
    }
    
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            context!.delete(viewController.listName[indexPath.row])
            viewController.listName.remove(at: indexPath.row)
            viewController.saveList()
            self.tableView.reloadData()
            
        }

    }
    
   override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
              performSegue(withIdentifier: "items", sender: self
          }
}

Here is the code for the Second View Controller:

import UIKit
import CoreData

class RootListsViewController: UITableViewController {
    
    var titleName = ""
    var newListItem : String = ""
    var item : [ListItem] = [] //listItems Coredata
    let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        
    }
    
    @IBAction func addItem(_ sender: Any) {
        
        
        
    }
    
    
    @objc func returnHome(sender: UIBarButtonItem) {
        
    performSegue(withIdentifier: "home", sender: self)
        
    }
    
    @objc func returnList(sender: UIBarButtonItem) {
        
        //performSegue(withIdentifier: "list", sender: self)
        tabBarController?.selectedIndex = 0
        
    }

    
    // MARK: - Table view data source

     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         // #warning Incomplete implementation, return the number of rows
        return item.count
     }

     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let cell = tableView.dequeueReusableCell(withIdentifier: "listCell", for: indexPath)
        
        let result = item[indexPath.row]
        cell.textLabel?.text = ("\(String(result.name!))")

         return cell
     }
    
   override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        //performSegue(withIdentifier: "items2", sender: self)
    
    
        
    }
    
    var label: UILabel {
        let label = UILabel(frame: tableView.bounds)
        label.text = "empty"
        return label
    }
    
    func saveList() {
           
           do {
             try context!.save()
           } catch {
             print("Error saving context \(error)")
         }
           
       }
       
       func loadList() {
             
             let request : NSFetchRequest<ListItem> = ListItem.fetchRequest()
             
             do{
               item = try context!.fetch(request)
             } catch {
                 print("Error loading categories \(error)")
             }
         }
    
    override func viewDidAppear(_ animated: Bool) {
          super.viewDidAppear(false)
          loadList()
          self.tableView.reloadData()
      }
}

Sorry if this is a silly question, can't seem to find answers.

Upvotes: 1

Views: 70

Answers (2)

Alrik
Alrik

Reputation: 100

In the fist VC create the function:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "items" {
        let controller = segue.destination as! RootListsViewController
        controller.XXX = sender.XXX
    }
}

where XXX is the variable (o stuct) you want to pass, it have to be defined as a var in the second VC. For exemple, if I click on a row i can say:

controller.itemPassed = sender.textLabel?.text

and itemPassed have to be declared in the second VC as a String. The sender is the row you are tapping, the variable passed can be everithing, normaly is a struct or a class hidden in the row. If you are using Core Data you can simply pass an index and then extract the required info form core data in the second VC. As you passed your filter you swtch the dataSource and load the new VC.

Edited for bad layout

Upvotes: 0

MStrapko
MStrapko

Reputation: 521

Best practice would be to setup different view controllers for the different table views, as in, you would want to have separate screens to display the different data sources. However, in theory, you should be able to do what you're attempting to do by programmatically switching the data source on the table view to a different data source and then refreshing the view:

tableView.dataSource = newDataSource
tableView.reloadData()

Not entirely clear on what you're trying to do, but that should get you in the right direction.

Upvotes: 0

Related Questions