2014年11月4日火曜日

【iOS8 対応】editActionsForRowAtIndexPathで標準メーラーのようなedit modeを実現するために

iPhoneの標準メーラーに搭載されているUIで
各cellをスワイプすると「削除」とかボタンがにゅるっと出てくるのありますよね?

あれがiOS8からuitableviewのdelegateメソッドとして使えるようになりました。

tableView:editActionsForRowAtIndexPath

基本的な使い方は、ブログで多く取り上げられていますが、

-(NSArray*)tableView:(UITableView*)tableView editActionsForRowAtIndexPath:(NSIndexPath*)indexPath {

UITableViewRowAction *deleteAction
= [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive
title:@"delete"
handler:^(UITableViewRowAction *action,NSIndexPath *indexPath) {

// ボタン押したときの処理

}

// ボタンの数はここで決まる
return @[deleteAction];

}

// これないとダメ
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexpath *)indexPath
{
 
}

以上が基本的な実装です。


が、これには欠点があります。
iOS7です。

現時点ではiOS7にも対応させなさいよ、っていうオーダーが多いと思います。

そこで対応方法をちょっぴりはまったので記載しておきます。


まず、iOS7でもこの状態でボタンが出てきます(なぜ?w)。

ただ、ボタンを押してもUITableViewRowActionのブロック内にきません。

どこいった?

ここで活きてくるのが、//これないとだめ って書いた
tableView:commitEditingStyle:forRowAtIndexPath
ここです。

これは本来、uitableviewのedit modeをYESにしたときに通るところなんですが、
今回の実装方法でボタンを押したときにも通ります。

ここはiOS8では通りません。


なので、ブロック内と同じアクションを書いておけばOKです。



さらに、特定のセルだけこのスワイプしてボタンが出るようにする場合は、
iOS7 8どちらも対応させるには、editActionsForRowAtIndexPathで
セルの判別しただけではダメで、

tableView:canEditRowAtIndexPath
でセル判別しないといけません。


tableView:editActionsForRowAtIndexPath
これがなんでiOS7で動くかなぞです。。。