超簡単!テーブルのセルの長押しでアクションシートを出す

テーブルに長押しジェスチャーを追加する場合、編集モードでは並べ替えのドラッグと干渉してしまうので工夫が必要です。

もし、長押しで指の追跡やリリースを検出しなくて良い(何らかのアクションを起こすだけ)なら前の記事で書いたMenuControllerのメソッドを拝借すれば簡単です。

- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
    // ここではジェスチャーが効いているのでハイライトが消せない
    // reloadして強制リセット
    // Cancel gestures during tracking
    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleActionSheet];
    if (alertController.popoverPresentationController != nil) {
        alertController.title = nil;
        alertController.message = nil;
        alertController.popoverPresentationController.sourceView = self.view;
        alertController.popoverPresentationController.sourceRect = [tableView rectForRowAtIndexPath:indexPath];
    }
    [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
    [self presentViewController:alertController animated:YES completion:nil];
    return YES;
}

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

- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
}

そもそもメニューは表示させてないので、UIMenuControllerWillShowMenuなどの通知は一切飛んできません。

ちなみに、この長押しジェスチャーはセル内のcontentViewにセットされています。iOS 10にて確認。