UITableViewCellEditControlとUITableViewCellReorderControlの画像を変更する(複数選択可能時のみ)

とってもニッチな記事です:smirk_cat:
参考にする人は少なそうですが、せっかく仕事で触ったのでまとめておきます:pencil:

# `UITableViewCellEditControl`, `UITableViewCellReorderControl`とは
`UITableView`で編集モードになったときに、左右に出てくる部品のことです。
![tableview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84917/fdfd62be-c9b9-21bf-cf3c-df4c679574e5.png)

編集モード？削除？並び替え？って感じの人はこちらの記事を見ると理解できるかと思います。
http://himaratsu.hatenablog.com/entry/tableview/editmode

# 画像を変更する

:warning:**この方法は`UITableView`の編集モードで複数選択が可能な場合にのみ正常に動作します**:warning:
:warning:**`tableView.allowsMultipleSelectionDuringEditing = true`を前提としています**:warning:

Debug View Hierarchyで見るとクラス名を知ることはできますが、コードからはこれらのクラス名を使うことはできません。
<img width="241" alt="スクリーンショット 2020-01-29 16.14.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84917/efc73c17-b535-4247-8e6e-b7df627eb940.png">
どうやら`UITableViewCell`の直下にいるらしいので、`subviews`で探せそうです。それぞれ`UIImageView`を持っていることもわかります。

`UITableViewCell`のサブクラスを作って、`UITableViewCellEditControl`と`UITableViewCellReorderControl`が持っている`UIImageView`に画像をセットする処理を書きます。

```swift:画像をセット
final class UITableViewCustomCell: UITableViewCell {
    
    private func setEditControlImage()  {
        // UITableViewCellEditControlが持つimageViewを取得
        let imageView = subviews.first { $0.description.contains("Edit") }?.subviews.first { $0 is UIImageView } as? UIImageView
        // セルの選択状態に応じて適当な画像をセット
        imageView?.image = isSelected ? #imageLiteral(resourceName: "thunder_black") : #imageLiteral(resourceName: "thunder_white")
    }
    
    private func setReorderControlImage() {
        // UITableViewCellReorderControlが持つimageViewを取得
        let imageView = subviews.first { $0.description.contains("Reorder") }?.subviews.first { $0 is UIImageView } as? UIImageView
        // 適当な画像をセット
        imageView?.image = #imageLiteral(resourceName: "swastika")
        // そのままだと横長の画像になってしまうのでモード変更
        imageView?.contentMode = .scaleAspectFit
    }
}
```

後は適当なタイミングで画像をセットする処理を呼び出します。

```swift:適当なタイミングで画像をセット
extension UITableViewCustomCell {
    
    // セルがハイライトされた
    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
        super.setHighlighted(highlighted, animated: animated)
        setEditControlImage()
    }
    
    // セルが選択された
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        setEditControlImage()
    }
    
    // セルの編集モードが変更された
    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)
        setEditControlImage()
        setReorderControlImage()
    }
}
```

これで画像を変更させることができました。
![table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84917/489e29b5-9729-4cb4-2c73-87d94ddb1ea5.png)


# 編集モードで複数選択以外にすると画像が戻ってしまう状況がある
編集モードで複数選択以外にすると、`UITableViewCellEditControl`をタップするか、並び替えをすると、`UITableViewCellEditControl`の画像がデフォルトのものに戻ってしまいます。
仕事では複数選択のときのみ考えればよかったので深く追いませんでしたが、どうすればうまくいくんでしょうか？？
![tabl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84917/6f8af64c-fcfb-ae06-15a5-15672bcbc3e0.png)

# おわりに
割と無理やり標準部品の画像を変更してみました:metal:
こういうのをやると、いつもプロパティ用意しておいてほしいなと思います:thinking:
OSのバージョンアップなどで使えなくなる可能性は十分にあるので、カスタムセルのビューでやるほうが無難かと思いますが、もしよければ使ってみてください！:raised_hands: