2013年6月5日 星期三

UITableView Delete Cell

開個Master-Detail研究一下基本的刪除方式, 使用Table的編輯模式應該是用下面這方法設定editing的BOOL值
[self.tableView setEditing:NO animated:YES];
[self.tableView setEditing:YES animated:YES];

而在Editing=YES系統產生自帶的Insert或Delete按鈕
搭配下面這方法藉由EditingStyle來判斷執行Insert或Delete的實作
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [_objects removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    }
}

而預設UITableViewCellEditingStyle都是Delete, 若要將EditingStyle改為Insert則使用
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellEditingStyleInsert;
}
若是改為Insert之後, 在commitEditingStyle方法內的
if (editingStyle == UITableViewCellEditingStyleInsert)這段判斷實作出來
仿造Delete做法, 只是改為將Object增加, 然後[tableView insertrow~ ];




而目前專案自訂Cell, 要自定刪除方式
也不能說是自定, 只是不要醜陋的預設Delete圖案, 而且也不要縮排
上面這有一些方法用不到了, 先來做取消縮排, 整個做法只是很簡單的改造一下Master-Detail

開始前先做個CustomCell, 有一個Delete Button, 設tag=100, 預設隱藏

下面方法就名稱來看是問說要不要縮排
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
    return NO;
}
回傳NO之後理論上應該是就可以了, 但結果還是不行, 預設的Insert或是Delete按鈕還是會跑出來, 所以多加了下面這行
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellEditingStyleNone;
}
將EditingStyle設為None, 這樣就成功把縮排取消了


然後我在NavigationBar做了一個按鈕, 做為設定TableView Editing切換用
- (IBAction)customBtn:(id)sender {
    if ([self.tableView isEditing]) {
        [self.tableView setEditing:NO animated:YES];
        
        for (UITableViewCell *cell in [self.tableView visibleCells]) {
            UIButton *btn = (UIButton *)[cell viewWithTag:100];
            [btn setHidden:YES];
        }
    }
    else {
        [self.tableView setEditing:YES animated:YES];
       
        for (UITableViewCell *cell in [self.tableView visibleCells]) {
            UIButton *btn = (UIButton *)[cell viewWithTag:100];
            [btn setHidden:NO];
        }
    }
}
這裡面比較有趣一點的是, 我用個for來跑目前"可見"的Cell, 來設置刪除按鈕是否顯示
而不可見的按鈕, 在捲動到要用的時候都會跑cellForRowAtIndexPath, 所以我在下面加了一句判斷式
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    UIButton *btn = (UIButton *)[cell viewWithTag:100];
    if (tableView.isEditing) {
        [btn setHidden:NO];
    }
    else {
        [btn setHidden:YES];
    }
    
    return cell;
}
若是正在編輯, 之後Reuse產出來的Button, 或是按下Add新增的Cell的Button都會顯示


再來就是如何從每個自定的Delete Button中取得IndexPath, 就下面這兩句
CGPoint point = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point];

完整實現刪除TableCell的話就這樣
- (IBAction)delete:(id)sender {
    CGPoint point = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point];
    
    [_objects removeObjectAtIndex:indexPath.row];

    [self.tableView beginUpdates];
    [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView endUpdates];
}

這裡是我完整的練習Project

沒有留言:

張貼留言