Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reload detail view when table cell is deleted - Swift

I have a split view controller (master-detail). I'm optimizing it for the iPhone 6 Plus.

Here's the issue. When you select a cell, it performs a show-detail segue and displays the cells information in the detailed view. However, when you delete a cell, the detailed view keeps the cells info even though the cell no longer exists.

Here's an example:

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {

    //code that deletes my cell/not needed for example

    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Left)

    let splitController = self.splitViewController!.viewControllers
    self.detailViewController = splitController.last? as? detailedController
    if let detail = detailViewController {
        detail.title = "Select an item" 
        //detail.title is a variable in the view controller
        //on the views "viewDidLoad" it sets a label.text as title.
        }
    }
}

I want perform the action: detail.title = "Select an item", so that the view is no longer displaying the deleted cell. I tried making a new segue through code. No luck.

Ideas?

like image 478
JoeBayLD Avatar asked Oct 20 '22 22:10

JoeBayLD


1 Answers

Do the following:

  1. Make sure your segue that sets the detail view controller has an identifier. In the sample Master-Detail project the identifier is "showDetail". You can find the identifier by selecting the segue in the Document Outline View of the project, and then looking in the Identifier Field in the Attributes Inspector for the segue.

  2. Call this segue programmatically when you delete a row:

    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Call showDetail when in a splitViewController and 2 view controllers
            // are present
            if self.splitViewController?.viewControllers.count == 2 {
               self.performSegueWithIdentifier("showDetail", sender: self)
            }
            ...
    
  3. In your prepareForSegue make sure you check the selected row. When you call the segue from the cell deletion code no row will be selected and indexPathForSelectedRow() will return nil:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showDetail" {
            if let indexPath = self.tableView.indexPathForSelectedRow() {
                // set up destination view controller in the normal way
                ...
            } else {
                // No row was selected which means either this is the initial setup
                // or we came here from the row delete code
                let splitController = self.splitViewController!.viewControllers
                self.detailViewController = splitController.last? as? detailedController
                if let detail = detailViewController {
                    detail.title = "Select an item"
                    ...
            }
        }
    }
    

Note: If your detail view controller has a default state for when detail.title is not set, and this default state is what you want your destination view controller to look like if no row has been selected, then you don't even need the else clause in prepareForSegue. This is the case for the sample Master-Detail iOS app. It is only necessary to call the segue programmatically from the edit code, and it all just works.

like image 95
vacawama Avatar answered Nov 03 '22 17:11

vacawama