Swift 3: Creating a custom edit button for UITableViewController

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).

Smug Piggy for the Latest Men's & Women's T-shirts

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.

Leave a Reply

Your email address will not be published. Required fields are marked *