My brief was pretty simple for this Swift module: click on a row to view a member’s detail page. Click on the edit button beside a member to update data. Accessing the detail page turned out to be very straight forward usingĀ self.tableView.indexPathForSelectedRow!.row to select the relevant member from our entity.
My difficulty arose when trying to select the relevant member using an edit button inside a row. This is where I first came across superview (which is now a common tool in our developing arsenal).
Our entity is first queried and loaded into the List variable inside the ViewDidAppear function. We have also used a sort descriptor to sort our members by last name.
override func viewDidAppear(_ animated: Bool) { let TheContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext let TheRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Members") // Order by last name let sortDescriptor = NSSortDescriptor(key: "lastname", ascending: true) let sortDescriptors = [sortDescriptor] TheRequest.sortDescriptors = sortDescriptors List = try! TheContext.fetch(TheRequest) tableView.reloadData() }Our row and edit buttons are connected to their relevant detail pages using segues. Each segue has its own own id that can be referenced in our code. To edit an item, we use superview to navigate up the view hierarchy to find the relevant cell identifier. Very handy. I initially used if statements for our segues but was advised by fellow programmers that the switch statement was more… Swifty!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { switch segue.identifier! { case "sgViewMember": guard let selectedCell: NSManagedObject = List[self.tableView.indexPathForSelectedRow!.row] as? NSManagedObject else { fatalError("Error loading data") } let vc: ViewMemberViewController = segue.destination as! ViewMemberViewController vc.dataFirstname = selectedCell.value(forKey: "firstname") as! String vc.dataLastname = selectedCell.value(forKey: "lastname") as! String vc.dataPhone = selectedCell.value(forKey: "phone") as! String vc.dataEmail = selectedCell.value(forKey: "email") as! String vc.data = selectedCell case "sgEditMember": if let btnEdit = sender as? UIButton { let cell = btnEdit.superview?.superview as! UITableViewCell let indexPath: IndexPath = self.tableView.indexPath(for: cell)! as IndexPath guard let selectedCell: NSManagedObject = List[indexPath.row] as? NSManagedObject else { fatalError("Error loading data") } let vc: AddMemberViewController = segue.destination as! AddMemberViewController vc.dataFirstname = selectedCell.value(forKey: "firstname") as! String vc.dataLastname = selectedCell.value(forKey: "lastname") as! String vc.dataPhone = selectedCell.value(forKey: "phone") as! String vc.dataEmail = selectedCell.value(forKey: "email") as! String vc.data = selectedCell } default: break } }This is our attempt, it seems to work well, but as per usual we would love your feedback.