Search code examples
iosswiftseguecloudkit

Passing CloudKit records from TableViewController A to TableViewControllerB on segue with dynamic prototype cells


I'm able to populate TableViewController A with records from CloudKit (var restaurants: [CKRecord] = []) but not sure how to pass a subset of [CKRecord] onto TableViewController B since both controllers have dynamic prototype cells and have their respective view cells defined as UITableViewCell. Further, the segue should only be triggered when the user taps the navigation item on TableViewController A (not when cell is selected).

Here's how I've implemented cellForRowAt

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "dataCell", for: indexPath) as! RestuarantViewCell

   // Configure the cell...
    let restaurant = restaurants[indexPath.row]
    cell.RestNameLabel?.text = restaurant.object(forKey: "name") as? String
    cell.RestDescLabel?.text = restaurant.object(forKey: "desc") as? String

    if let image = restaurant.object(forKey: "image"), let imageAsset = image as? CKAsset {
        if let imageData = try?Data.init(contentsOf: imageAsset.fileURL) {
            cell.RestImageView?.image = UIImage(data: imageData)
        }
    }

    return cell
}
  1. When a user performs a leading swipe, add that item to a list (var list: [CKRecord] = [])

override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

let addAction = UIContextualAction(style: .normal, title: "Save") { (action, sourceView, completionHandler) in
    //Add to list
    self.list.append(self.restaurants[indexPath.row])
    print(self.list)

    //Delete row and reload tableView i.e. tableView.reloadData()
    self.tableView.deleteRows(at: [indexPath], with: .fade)

    //Call completion handler to dismiss the action button
    completionHandler(true)
}

//Configuring delete button
addAction.backgroundColor = UIColor(red: 76, green: 217, blue: 100)

//Create button for user swipe
let swipeConfiguration = UISwipeActionsConfiguration(actions: [addAction])

return swipeConfiguration

}

  1. This list is only visible when the user tap the navigation item on TableViewController A (not when cell is selected). Segue "showList" has been implemented in storyboard from nav item to TableViewController B.

In short, TableViewController B is a list of restaurant (name, image) saves from TableViewController A

Should I use func prepare(for segue: UIStoryboardSegue, sender: Any?) or perhaps save this swipe to the cloud and fetch it again in TableViewController B?

Appreciate your time and suggestions!


Solution

  • Yes, I would use prepare for segue as you've mentioned. Make the restaurants array a class property on both table A and table B.

    Something like this:

    //Table View Controller A
    class TableViewA: UIViewController{
      var restaurants = [CKRecord]()
    
      override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
        if segue.identifier == "NameThisInYourStoryboard"{
          let vc = segue.destinationController as! TableViewB
          vc.restaurants = self.restaurants //Pass the data
        }
      }
    }
    
    //Table View Controller B
    class TableViewB: UIViewController{
      var restaurants = [CKRecord]()
    }
    

    This all presupposes that you set up the delegate and datasource of your controllers, and define the segue in your storyboard from A's table row tap to show table B.