1

i'm trying to delete a cell from UITableView in swift, i follow this tutorial: http://www.ioscreator.com/tutorials/delete-rows-table-view-ios8-swift the problem is my UITableView has many section, so i can't delete the cell the way like the tutorial. any one know how to delete cell form table with multiple section? thanks.

Code cracker
  • 3,105
  • 6
  • 37
  • 67
Rawan
  • 1,589
  • 4
  • 23
  • 47

4 Answers4

2

You cannot delete multiple cells at once with the method described in the tutorial. That will only work for single cell. If you select multiple cells and use button, for example, to trigger delete action, your code could look something like this:

if let indexPaths = tableView.indexPathsForSelectedRows() as? [NSIndexPath] {
    for indexPath in indexPaths {
        // one by one remove items from your datasource
    }

    tableView.deleteRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
} 
Kirsteins
  • 27,065
  • 8
  • 76
  • 78
1

Instead of using numbers[row] in the example you can use numbers[section][row]. So the code will look like:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return numbers[section].count
  }

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == UITableViewCellEditingStyle.Delete {
      numbers[indexPath.section].removeAtIndex(indexPath.row)    
      tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
    }
  }
kabarga
  • 803
  • 6
  • 11
  • thanks for your help. but i get an exception when run the app, the exception is: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).' why? – Rawan Apr 01 '15 at 12:08
1

Neither of answers worked for me. Swift Array indexes are updated upon removal hence for-in loop for indexes from .indexPathsForSelectedRows() provided unexpected results i.e. wrong data/tables removed and eventually crash with index outside of array bounds error. Found good (but really outdated) Objective-C iOS Developer Library example. But it utilised NSMutableArray removeObjectsAtIndexes method, not present with Swift Array. Anyway a good deal of useful tricks in there so worth take a look. The method which work for me is part from that example but instead of removeObjectsAtIndexes do-while is used to remove rows one by one until all selected rows are removed. The method below called by UIAlertAction similar to Apple example.

  func deleteSelectedRows() {

    // Unwrap indexPaths to check if rows are selected
    if let _ = tableView.indexPathsForSelectedRows() {
      // Do while all selected rows are deleted
      do {

      if let indexPath = tableView.indexPathForSelectedRow(){
        //remove from table view data source and table view
        self.dataSource.removeAtIndex(indexPath.row)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
        }

      } while tableView.indexPathsForSelectedRows() != nil

    }else{
      // Delete everything, delete the objects from data model.
      self.dataSource.removeAll(keepCapacity: false)

      // Tell the tableView that we deleted the objects.
      // Because we are deleting all the rows, just reload the current table section
      self.tableView.reloadSections(NSIndexSet(index: 0), withRowAnimation: .Automatic)
    }
    // Exit editing mode after the deletion.
    self.tableView.setEditing(false, animated: true)
  }

Edit: While do-while did it trick for small example I've been working with (jus starting with swift) It's not efficient. Either extending Array or make data source Equatable and use find() or .filter is preferable.But I'm sure there should be a simpler way. The one I'm using now is described on link below:

http://www.rockhoppertech.com/blog/swift-remove-array-item/

func == (lhs: myDataSource, rhs: myDataSource) -> Bool {
  if lhs.data == rhs.data &&
    lhs.otherData == rhs.otherData {
      return true
  }
  return false
}

struct myDataSource: Equatable {
 let data: String
 let otherData: String
}

And then:

if let selectedRows = tableView.indexPathsForSelectedRows(){
  var objectsToDelete = [myDataSource]()
  for selectedRow in selectedRows {
    objectsToDelete.append(myDataSource[selectedRow.row])
  }
  for object in objectsToDelete {
    if let index = find(myDataSource, object){
      myDataSource.removeAtIndex(index)
    }
  }
}
tableView.deleteRowsAtIndexPaths([selectedRows], withRowAnimation: .Automatic)
0

try to this. this works fine. But don't forget to this before. func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { return true }

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
{
    if editingStyle == .Delete
    {
        arrayOfnames.removeAtIndex(indexPath.row)
        self.tableViewww.reloadData()
    }
}