Search code examples
iosswiftuitableviewsegue

How to perform a different segue when in Edit mode (in UITableView)?


I am creating a simple iPhone app using UITableView. I am using the default MasterDetail application template. Right now (in Edit mode) when I press any of the table cells nothing happens. However, when I am in normal mode the detail segue is initiated. How to override the Edit mode so that I initiate a custom segue to go to a different UIViewController.

P.S.: I still want to preserve the inherit delete functionality.

This is my code in my MasterViewController:

class MasterViewController: UITableViewController {
let kFileName: String = "/resolutionData.plist"
var resolutions = [Dictionary<String,String>]()
var achievedResolutions = [Dictionary<String,String>]()
// TO DO create a class to get this array
let iconArray = ["Fish","Fly","Heart","HelpingHand","Melon","Star","Tentacles","Volunteering"]

override func awakeFromNib() {
    super.awakeFromNib()
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.navigationItem.leftBarButtonItem = self.editButtonItem()

    let addButton = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "insertNewObject:")
    self.navigationItem.rightBarButtonItem = addButton


    //extract the path
    NSLog(dataFilePath())
    /**
    *   Check where is the sandbox of the application
    *   and if there is read from the data file and story it to "objects" array
    */
    if NSFileManager.defaultManager().fileExistsAtPath(dataFilePath()){
        var temp = NSArray(contentsOfFile: dataFilePath()) as! [Dictionary<String,String>]

        for res in temp{
            if res["isAchieved"] == "Y"{
                achievedResolutions.append(res)
            }else{
                resolutions.append(res)
            }
        }

        //... if there is not - create it
    } else {
        let data =  [["name":"Resolution name test","startingDate":"24-11-15","achievingDate":"01-01-2016","icon":iconArray[0],"isAchieved":"N"] as NSDictionary] as NSArray
        //if the file does not exist...
        if !NSFileManager.defaultManager().fileExistsAtPath(dataFilePath()){
            //... create it
            NSFileManager.defaultManager().createFileAtPath(dataFilePath(), contents: nil, attributes: nil)
        }
        //write to it
        data.writeToFile(dataFilePath(), atomically: true)
    }

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func insertNewObject(sender: AnyObject) {
    performSegueWithIdentifier("editDetails", sender: sender)
}

func saveDateToFile(){
    let data =  resolutions as NSArray
    data.writeToFile(dataFilePath(), atomically: true)
}

func notifyTableViewForNewInsertion(){
    let indexPath = NSIndexPath(forRow: 0, inSection: 0)
    self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)

}

// MARK: - Segues

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showDetail" {
        if let indexPath = self.tableView.indexPathForSelectedRow() {
            let object = resolutions[indexPath.row] as Dictionary
        (segue.destinationViewController as! DetailViewController).detailItem = object
        }
    }

}

// MARK: - Table View

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 2
}

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    if section == 0 {
        return "Active"
    }else{
        return "Achieved"
    }
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 0 {
        return resolutions.count
    }else{
        // TODO replace that with an actual array count
        return achievedResolutions.count
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
    if indexPath.section == 0{
        let object: AnyObject? = resolutions[indexPath.row] ["name"]
        cell.textLabel!.text = object as? String
        cell.detailTextLabel!.text = resolutions[indexPath.row]["achievingDate"]
        cell.imageView!.image = UIImage(named: resolutions[indexPath.row]["icon"]!)
    } else {
        let object: AnyObject? = achievedResolutions[indexPath.row] ["name"]
        cell.textLabel!.text = object as? String
        cell.detailTextLabel!.text = resolutions[indexPath.row]["achievingDate"]
        cell.imageView!.image = UIImage(named: resolutions[indexPath.row]["icon"]!)
    }
    return cell
}

override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        resolutions.removeAtIndex(indexPath.row)
        saveDateToFile()
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    } else if editingStyle == .Insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    }
}


func dataFilePath() -> String{
    let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)

    //get the first path and convert it to str
    let docDicrectyory: String = paths[0] as! String

    return  "\(docDicrectyory)\(kFileName)"

}

}

Solution

  • Override willBeginEditingRowAtIndexPath: function. this willbe call before start editing. there you can initialize a global variable.

    @property(nonatomic, String) BOOL editing
    

    and in the

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
    
       if (editing) {
    
           if([[segue identifier] isEqualToString:@"identifierOne"]){
    
    
           }else if([[segue identifier] isEqualToString:@"identifierTwo"]){
    
           }
       }    
    }