web-dev-qa-db-ja.com

UITableViewスワイプにボタンを追加する

現在、NSFetchedResultsControllerを使用してテーブルビューを処理しています。スワイプ操作で削除ボタンのような追加のボタンを追加する方法はあるのでしょうか?

それをサブクラス化することを考えています。しかし、ヘルプドキュメントで私の問題に関連するものは何もありません。

前もって感謝します。

17
AlexWei

タイトルは誤解を招くものです。 NSFetchedResultsControllerは、最終目標とは無関係です。サブクラス化は必要以上の作業を作成するだけなので、調べたいのはUITableViewRowActionです。これは非常に簡単に、新しいUIAlertControllerと同様に処理できるため、すでにUIAlertControllerを使用している場合は、非常に快適に感じるはずです。

UITableViewRowActionの簡単な概要( the docs から直接):

指定された行のスワイプに応答して表示するアクションをデリゲートに要求します。 (必須)テーブル行の1つにカスタムアクションを提供する場合は、このメソッドを使用します。ユーザーが行を水平方向にスワイプすると、テーブルビューによって行のコンテンツが横に移動し、アクションが表示されます。アクションボタンの1つをタップすると、アクションオブジェクトに保存されているハンドラーブロックが実行されます。このメソッドを実装しない場合、ユーザーが行をスワイプすると、テーブルビューに標準のアクセサリボタンが表示されます。

始める前に、いくつか注意点があります:

  • AppleはこれをiOS8に実装したので、展開ターゲットについて慎重に検討してください。厳密にi0S8向けにコーディングしている場合、これはサードパーティのライブラリやカスタムUITableView編集スタイルの作成に代わる迅速で簡単な方法です。 iOS7との互換性を維持することを目的とする場合、この形式ではオプションが制限されます。 サイドノートこれはコードに致命的なエラーを引き起こしません。iOS7アプリはクラッシュしませんが、カスタムアクションは単に表示されません。
  • タイトル以外のカスタマイズはあまりありません
  • これの長所は、すべてがブロックで処理されることです

いずれにしても、カスタムUITableViewRowActionを実装するには、まず次のメソッドを呼び出してテーブルが編集可能であることを確認する必要があります。

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    //Obviously, if this returns no, the edit option won't even populate
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    //Nothing gets called here if you invoke `tableView:editActionsForRowAtIndexPath:` according to Apple docs so just leave this method blank
}

少なくとも、これらは次に進む前に宣言する必要がある2つのメソッドです。

行アクションボタンを実際にカスタマイズするには、次の一般的なガイドラインに従います。

ステップ1tableView:editActionsForRowAtIndexPath:メソッドを実装します

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

ご覧のとおり、これはNSArray型のインスタンスメソッドであるため、配列を返す必要があります。

STEP 2配列で渡すアクションオブジェクトを追加します。例:

{

UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
    // Delete something here
}];

UITableViewRowAction *more = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@" More " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
    //Do whatever here : just as an example :
    [self presentUIAlertControllerActionSheet];
}];

}    

これらの行アクションのいくつかのプロパティを変更できますが、完全なカスタマイズオプションについてはドキュメントを参照してください。

行アクションの背景色をカスタマイズするには、ボタン内の他のほとんどのアクションと同じように実行します。

delete.backgroundColor = [UIColor redColor];
more.backgroundColor = [UIColor colorWithRed:0.188 green:0.514 blue:0.984 alpha:1]; //arbitrary color

ステップ3前述のように、インスタンスメソッドで配列を返す必要があるため、完全なコードは次のようになります。

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

    UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
    {
        // Delete something here
    }];
    delete.backgroundColor = [UIColor redColor];

    UITableViewRowAction *more = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@" More " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
    {
        //Just as an example :
        [self presentUIAlertControllerActionSheet];
    }];
    more.backgroundColor = [UIColor colorWithRed:0.188 green:0.514 blue:0.984 alpha:1];

    return @[delete, more]; //array with all the buttons you want. 1,2,3, etc...
}    

詳細参照: ドキュメントへのリンク


編集済みSwift構文

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?  {

var delete = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
    //Do something
})
delete.backgroundColor = UIColor.redColor()

var more = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "More" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
    //Do something
})
more.backgroundColor = UIColor.blueColor()

    return [delete, more]
}
49
soulshined

@soulshinedに対するすべての称賛が受け入れられた回答です。

Swiftの3つのバージョン:

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    let delete = UITableViewRowAction(style: .default, title: "Delete") { (action:UITableViewRowAction, indexPath:IndexPath) in
        print("delete at:\(indexPath)")
    }
    delete.backgroundColor = .red

    let more = UITableViewRowAction(style: .default, title: "More") { (action:UITableViewRowAction, indexPath:IndexPath) in
        print("more at:\(indexPath)")
    }
    more.backgroundColor = .orange

    return [delete, more]
}
11
Gunhan