テーブルのセルに削除やカスタムのメニューを表示させる

テーブルにはUIMenuControllerのメニューを表示させるデリゲートが用意されていますが、項目をカスタマイズしたり、内蔵のDeleteを出したい時にはCellのサブクラスに一手間加える必要があります。しかも押した時のアクションはそのCell内のメソッドで受けるようになっているので、VC側で記述できるように工夫しておきます。

@implementation MyCell

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if (action == @selector(delete:)) {
        return YES;
    }
    return NO;
}

- (void)performSelector:(SEL)aSelector sender:(id)sender {
    UIView *superview = self;
    while ((superview = superview.superview) != nil) {
        if ([superview isKindOfClass:[UITableView class]]) {
            UITableView *tableView = (id)superview;
            NSIndexPath *indexPath = [tableView indexPathForCell:self];
            if (indexPath != nil) {
                [tableView.delegate tableView:tableView performAction:aSelector forRowAtIndexPath:indexPath withSender:sender];
            }
            break;
        }
    }
}

- (void)delete:(id)sender {
    [self performSelector:_cmd sender:sender];
}

@end

セルからsuperviewを遡ってテーブルを探します。セル側でこうしておくと、Deleteが押された時の処理はテーブルのdelegateに渡されるので、実際の処理はVC側で実装できます。

- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    return YES;
}

- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    if (action == sel_registerName("delete:")) {
        // 削除処理
    }
}