實現 UITableViewCell的批量刪除

weixin_34075551發表於2015-10-25

上一篇文章提到可以非常快捷實現簡單的UITableView的刪除操作,但是有時候無法滿足需求,比如:使用者可以選擇cell來決定哪些cell需要刪除(一起被刪除)。

UITableView有一個屬性allowsMultipleSelectionDuringEditing,如果這個屬性被設定為YES,當UITableView進入編輯模式的時候,UITableView出現的不再是預設的樣式(左面紅色的-按鈕),而是會在左面出現可選擇的按鈕。

當使用者點選這些按鈕,那麼這行cell就相當於被選中;如果再點選,則會自動取消選中。

用程式碼來實現上述操作:

- (void)viewDidLoad 
{
    [super viewDidLoad];
    // 設定tableView在編輯模式下可以多選,並且只需設定一次
    self.tableView.allowsMultipleSelectionDuringEditing = YES;
}

// 當使用者點選一個按鈕的時候會進入這個方法,這個方法是讓tableView進入編輯模式
- (IBAction)makeSelectable
{
    [self.tableView setEditing:!self.tableView.isEditing animated:YES];
}

此時點選按鈕就會進入編輯模式,在每個cell左面就會出現可選擇按鈕,點選就可以選中多個cell。

注意如果在makeSelectable方法中是這樣實現的:

- (IBAction)makeSelectable
{
    [self.tableView setEditing:YES animated:YES];
}

會發現依然會出現編輯模式,但是此時編輯模式退不出去的。所以要在makeSelectable方法中將editing設定為!self.tableView.isEditing,這樣再次點選這個按鈕,editing的值就會取反,這樣可以成功進入和退出。

此時選中了多個cell,但是我們的目的是刪除選中多個cell並進行刪除操作。我們又要去哪裡找到這些選中的cell呢?

不用擔心,UITableView又給我們提供相關屬性啦… Lol

通過UITableView的indexPathsForSelectedRows,我們可以拿到選中的cell的indexPath,這些indexPath被放到了indexPathsForSelectedRows這個陣列裡。

此時我們需要另一個按鈕來真正執行多行刪除操作。並且給這個按鈕繫結一個方法名為removeSelectedCells

- (IBAction)removeSelectedCells {
    NSMutableArray *deleteBooks = [NSMutableArray array];
    for (NSIndexPath *indexPath in self.tableView.indexPathsForSelectedRows) {
        [deleteBooks addObject:self.books[indexPath.row]];
    }

    [self.books removeObjectsInArray:deleteBooks];
    [self.tableView reloadData];
}

在這個方法中,我們首先遍歷self.tableView.indexPathsForSelectedRows這個陣列得到各個選中的cell的indexPath,然後在self.books中根據indexPath來找到對應的book並加入到一個臨時陣列deleteBooks中。deleteBooks陣列中表示的就是選中的cell對應的資料模型,然後在self.books中將這些選中的模型刪除,接著重新整理tableView。

注意,這裡一定要在self.books中刪除整個選中的模型陣列,而不是直接在for迴圈中直接在self.books中刪除每個模型。

- (IBAction)removeSelectedCells {
    for (NSIndexPath *indexPath in self.tableView.indexPathsForSelectedRows) {
        [self.books removeObjectAtIndex:indexPath.row];
    }
    [self.tableView reloadData];
}

這樣雖然看來簡單不少並且不需要一個臨時陣列,但是這種做法是會出現錯誤的。舉例來說,當刪除第一個模型的時候,此時第二個模型的陣列下標變為了0,而indexPath對應的row則是1。也就是說本意是刪除的前兩個模型,那麼實際刪除的則是第一個和第三個模型。所以這種做法並不可取。

相關文章