【Swift】UIBarButtonItemの背景色を設定したい

## 1. はじめに


LINEアプリの「トークリスト編集」のような、UIBarButtonItemの背景色を設定したい。

(LINEアプリより)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139949/4549a88a-64a5-2b11-de9f-61ecc20bdd78.png" width="300px">

UIToolBarのUIBarButtonItemに背景色を設定したいときに、

UIBarButtonItemのドキュメントの[外観のカスタマイズ](https://developer.apple.com/documentation/uikit/uibarbuttonitem#1656861)を見ても、
background colorのような背景色を変えるAPIは用意されていませんでした。 

(参考：https://teratail.com/questions/187706)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139949/c204c41b-dfdb-37f6-e2a7-7cb70ec7293a.png" width="300px">

そこで今回は、UIBarButtonItemの`setBackgroundImage`で、
背景に**色だけのUIImageを生成する**方法を行ってみます。

至らぬ点など多々あると思いますが、コメントなど頂けたら幸いです。


## 2. 追加するコード

色だけのUIImageを生成するUIImage extensionを追加します。

```swift

/// UIImage+CommonUIBarButtonItem.swift

import UIKit

extension UIImage {
    
    /// - 色だけのUIImageを生成する
    class func colorImage(color: UIColor, size: CGSize) -> UIImage {
        UIGraphicsBeginImageContext(size)
        
        let rect = CGRect(origin: .zero, size: size)
        let context = UIGraphicsGetCurrentContext()
        context!.setFillColor(color.cgColor)
        context!.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        
        UIGraphicsEndImageContext()
        
        return image!
    }
}
```

## 3. toolBarを生成している記述に`setBackgroundImage`を追加する

詳しい説明は省略しますが、[こちら](https://ja.stackoverflow.com/questions/13163/uitoolbar-%E3%82%A2%E3%82%A4%E3%83%86%E3%83%A0%E3%81%AE%E4%BD%8D%E7%BD%AE%E3%82%92%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E3%81%8A%E6%95%99%E3%81%88%E4%B8%8B%E3%81%95%E3%81%84)を参考に`flexibleItem`を用いてアイテム間のスペースを調節しました。
また、safeAreaより下部の余白の高さ(HomeIndicator)をSafeAreaInsets.bottomから取得し、UIToolBarを生成する際にSafeArea対応を行いました。 

```swift

import UIKit

class TestViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
        
    }
    private func setup() {
        
        let toolBar = UIToolbar()
        let footerBarHeight: CGFloat = 50
        
        toolBar.frame = CGRect(x: 0, y: view.bounds.height - footerBarHeight - (UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0), width: view.bounds.width, height: footerBarHeight)
        
        // Flexible Space Bar Button Item
        let flexibleItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
        
        let okButton = UIBarButtonItem(title: "完了", style: .plain, target: self, action: #selector(tapOkButton(_:)))
        
        okButton.tintColor = UIColor.white
        
        let deleteButton: UIBarButtonItem = UIBarButtonItem(title: "削除", style: UIBarButtonItemStyle.plain, target: self, action: #selector(tapDeleteButton(_:)))
        
        deleteButton.tintColor = UIColor.white
        
        // 追加：ボタンの背景に青色だけの画像を追加
        okButton.setBackgroundImage((UIImage.colorImage(color: UIColor.blue, size: CGSize(width: 150, height: 40))), for: .normal, barMetrics: .default)
        
        // 追加：ボタンの背景に赤色だけの画像を追加
        deleteButton.setBackgroundImage((UIImage.colorImage(color: UIColor.red, size: CGSize(width: 150, height: 40))), for: .normal, barMetrics: .default)
        
        toolBar.setItems([deleteButton,flexibleItem,okButton], animated: true)
        self.view.addSubview(toolBar)
    }
    @objc func tapOkButton(_ sender: UIBarButtonItem) {
        print("tapOkButton")
    }
    @objc func tapDeleteButton(_ sender: UIBarButtonItem) {
        print("tapDeleteButton")
    }
}

```

## 4. 実行結果

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139949/aa99e2ec-b36d-bc16-4a98-9a21f68c4e2c.png" width="300px">

無事にUIBarButtonItemの背景色の設定を再現することができました。



## 参考にさせていただいた記事

- [単色のUIImageを作成する](https://dev.classmethod.jp/references/ios-8-colorimage/)
- [iPhoneXのSafeArea対処法](https://www.yaz.co.jp/tec-blog/%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9/638)