[iOS 8] UITableViewRowActionでセル編集機能をカスタマイズする

UITableViewCellの編集機能カスタマイズ

UITableViewCellをスワイプした際に編集する機能は、標準で提供されていましたが、その機能の詳細なカスタマイズに関しては、標準には提供されておらず、OSSを用いれば実現することが可能でした。

今回iOS 8で新しく標準のAPIとして編集機能カスタマイズのためのUITableViewRowActionクラスと、UITableViewDelegateに設定の為のtableView:editActionsForRowAtIndexPath:メソッドが追加されました。

サンプルコード

サンプルプロジェクト全体はこちらの方に上がっています。今回はその一部の実装を見ていくことにします。

import UIKit

class MYViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    let contents = ["aa", "bb", "cc"] // 表示するコンテンツ

    override func viewDidLoad() {
        super.viewDidLoad()

        // コンテンツ内容よりも多くのCellのセパレータを表示しないための処理
        tableView.tableFooterView = UIView()
    }

}

extension MYViewController: UITableViewDelegate {

    // こちらのメソッドでindexPathで指定されたCell毎のRowAction配列を設定します
    func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath)
        -> [AnyObject]? {
        let editAction =
            UITableViewRowAction(style: .Normal, // 削除等の破壊的な操作を示さないスタイル
            title: "edit"){(action, indexPath) in println("\(indexPath) edited")}
        editAction.backgroundColor = UIColor.greenColor()
        let deleteAction =
            UITableViewRowAction(style: .Default, // 標準のスタイル
                title: "delete"){(action, indexPath) in println("\(indexPath) deleted")}
        deleteAction.backgroundColor = UIColor.redColor()
        return [editAction, deleteAction]
    }

}

extension MYViewController: UITableViewDataSource {

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return contents.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)
        -> UITableViewCell {
            // モジュール名.クラス名をCellIdentifierとして使用しているため、MYTableViewCell.self.description()でその文字列を取得
            var cell =
            tableView.dequeueReusableCellWithIdentifier(MYTableViewCell.self.description(),
                forIndexPath: indexPath) as MYTableViewCell
            cell.nameLabel.text = contents[indexPath.row]
            return cell
    }

    // エディット機能の提供に必要なメソッド
    func tableView(tableView: UITableView,
        commitEditingStyle editingStyle: UITableViewCellEditingStyle,
        forRowAtIndexPath indexPath: NSIndexPath) {

    }
}

今回のカスタマイズ機能の肝はtableView:editActionsForRowAtIndexPath:メソッドです。

このメソッドの内部でUITableViewRowActionの配列を生成し、返り値として返しています。

UITableViewRowActionには次のイニシャライザが提供されており、カスタマイズされた編集ボタンのタイトル、スタイル、タップされた時のハンドラを指定することができます。

convenience init(style style: UITableViewRowActionStyle, // スタイル
           title title: String!, // タイトル
         handler handler: (UITableViewRowAction!, // ハンドラ
                          NSIndexPath!) -> Void)

このUITableViewRowActionにはbackgroundColorプロパティとbackgroundEffectプロパティがあり、背景色(UIColor)とエフェクト(UIVisialEffect)を指定できます。

尚、エディット機能の提供にはtableView:commitEditingStyle:forRowAtIndexPathメソッドを空のまま実装することが必要になっています。

実際に動かしてみる

上記コードを含んだサンプルコードを実際に動かしてみます。

サンプルではdeleteボタンやeditボタンをタップするとログが出力されるようになっています。

参考サイト