セル上に配置したボタンをタップしてスワイプするセルをもつUITableViewをつくる


![20190627.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40693/605fd0a2-3ecc-a44e-8d59-55c58615da5d.gif)


### 開発環境

+ XCode10.2.1
+ Swift5.0.1

また時間があいてしまった・・・。
テーブルの編集モードで表示される、編集ボタンに画像を使いたいと言われて、何も考えずに
OKとしたら、まさかの編集ボタンをカスタマイズ出来なかった為、止むを得ずオリジナルセルを使って
編集ボタンを押した時のような動作を再現しました。
ちなみにセルの編集はスワイプ操作だけではダメという前提があります。

まずカスタムセルを用意。
カスタムセルにはスワイプ後に表示されるボタンを配置し、その上にUIView、
更にその上にボタンとラベルを配置します。

<img width="858" alt="スクリーンショット 2019-06-29 00.13.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40693/2fa6bb30-3107-e7d8-322a-890620592eb2.png">

ポイントしてAutoLayoutでUIViewの左右のConstraintを平常時とスワイプ後の両方を
用意し、スワイプ後のConstraintのプロパティでinstalledのチェックを外しておく

<img width="858" alt="スクリーンショット 2019-06-29 00.13.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40693/a14f4d6d-37c8-6626-f6bf-959e305fd228.png">

後はConstraintをソースの方で平常時、スワイプ時でどちらをアクティブにするかで
で見た目は編集ボタンを押した際と同じような動きをします。
layoutIfNeeded()の動きをアニメーションで時間をかけるところがミソでしょうか

<img width="1397" alt="スクリーンショット 2019-06-29 00.26.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40693/2b6173cd-46d7-994b-9e57-3843c7c6239a.png">

セルのボタンの動きはtableviewのあるソースの方で対応します。
ボタンのtagと行数を連動させてどの行のボタンが押されたかを判定する為、
セルを追加したり削除したりするたびに、reloadData、もしくはオリジナルのテーブル再編集メソッドを動かしてやる必要があるので注意。

```swift

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "customCellID", for: indexPath) as! CustomCell

        let object = objects[indexPath.row] as! NSDate
        cell.titleLabel.text = object.description
        
        let button = cell.button
        button?.tag = indexPath.row
        button?.addTarget(self, action: #selector(editTaped(_:)), for: .touchUpInside)
        
        let deleteButton = cell.DeleteButton
        deleteButton?.tag = indexPath.row
        deleteButton?.addTarget(self, action: #selector(deleteTaped(_:)), for: .touchUpInside)
       
        if cell.isSwiping {
            cell.swipe()
        }
        
        return cell
    }

 //MARK: @Objc

 @objc
    func insertNewObject(_ sender: Any) {
        objects.insert(NSDate(), at: 0)
        let indexPath = IndexPath(row: 0, section: 0)
        tableView.insertRows(at: [indexPath], with: .automatic)
        
        tableView.reloadData()
    }
    
    @objc func editTaped(_ sender: UIButton) {
        let cell = self.tableView.cellForRow(at: IndexPath(row: sender.tag, section: 0)) as! CustomCell
        
        cell.swipe()
    }
    
    @objc func deleteTaped(_ sender: UIButton) {
        
        objects.remove(at: sender.tag)
        tableView.deleteRows(at: [IndexPath(row: sender.tag, section: 0)], with: .fade)
        tableView.reloadData()
    }

```

ざっくりとですが、以上。
全体のソースは[github](https://github.com/rnsm504/TapSwipeCellUsedTable)にあげているので良かったら参照下さい。

参考サイト

[AutoLayoutでスワイプできるUITableViewCellを実装する](https://tomoyaonishi.hatenablog.jp/entry/2014/10/13/230830)

[Is it possible to call editActionsForRowAt of UITableview manually?](https://stackoverflow.com/questions/51701351/is-it-possible-to-call-editactionsforrowat-of-uitableview-manually)