5

In my tableview, I only want certain cells to be able to drag to the left for some options based on a condition. The other cells should behave as if commitEditingStyle is disabled. Is this possible?

With the code below, I can add the actions when the conditions are met but the other cells still get the default "delete" action. How do I get rid of that delete action?

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
}

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {

    let object = items[indexPath.row]
    if object.name == "name" {

        // someAction
        var addAction = UITableViewRowAction(style: .Default, title: "+") { (action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void in
        }
        return [addAction]
    }
    return nil
}

With the code below I managed to enable and disable the actions. But only with the Delete button.

override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {

    let object = items[indexPath.row]
    if object.name == "joyce" {
        return UITableViewCellEditingStyle.Delete
    } else {
        return UITableViewCellEditingStyle.None
    }
}
Hendrik Smoels
  • 240
  • 3
  • 12

2 Answers2

5

You'll want a way to determine editable state based on your data model. For example:

class Message
{
    var subject : String
    var title : String
    var isEditable : Bool

    init(subject: String, title: String)
    {
        self.subject = subject
        self.title = title
        self.isEditable = true
    }
}

With this, you can easily handle the tableView:canEditRowAtIndexPath: delegate method. Your view controller should look something like this:

class ViewController : UIViewController, UITableViewDataSource, UITableViewDelegate
{
    var tableView : UITableView!
    var messages : [Message]

    // MARK: - UITableView Delegate

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return self.messages.count
    }

    func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
    {
        let message = self.messages[indexPath.row]
        return message.isEditable
    }
}

In some more complex examples it may be a computed property but the overall concept is the same.

Erik
  • 12,730
  • 5
  • 36
  • 42
2

It sounds like you're looking for optional func tableView(_ tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool.

From Apple documentation:

The method permits the data source to exclude individual rows from being treated as editable. Editable rows display the insertion or deletion control in their cells. If this method is not implemented, all rows are assumed to be editable.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
  • I forgot to add that i can manage to do exactly what i want, but only with getting the default delete action with the code `override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle { let object = items[indexPath.row] if object.name == "name" { return UITableViewCellEditingStyle.Delete } else { return UITableViewCellEditingStyle.None } }` Is it possible to use something similar to this? – Hendrik Smoels Mar 17 '15 at 22:11
  • If you disable editing for rows that do not match your condition, what's the difference between that and what you want? – Phillip Mills Mar 17 '15 at 22:15
  • sorry, i had the condition double. Got mixed up after trying to figure out for hours and mixing some things up :s, thanks anyway! – Hendrik Smoels Mar 17 '15 at 22:19