iOSでナビゲーションバーとステータスバーの色を別々に設定する

## 1. ナビゲーションバーのtintColorにステータスバーの色を設定する

```swift
if let navigationBar = navigationController?.navigationBar {
    navigationBar.tintColor = /* any color */
}
```

## 2. ステータスバーとナビゲーションバーをあわせた領域の透過画像を生成する

```swift:色から画像を作る関数
func createImage(color: UIColor, size: CGSize) -> UIImage {
    let rect = CGRect(origin: .zero, size: size)
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    UIColor.clear.setFill()
    UIRectFill(rect)
    let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return image
}
```

```swift
let baseImageSize = CGSize(
    widht: UIScreen.main.widht,
    height: navigationBar.frame.height + UIApplication.shared.statusBarFrame.height
)
let baseImage = createImage(color: .clear, size: baseImageSize)
```

## 3. ナビゲーションバー部の色を持つ画像をナビゲーションバーのサイズで生成する

```swift
let navigationBarImageSize = CGSize(
    widht: UIScreen.main.widht,
    height: navigationBar.frame.height
)
let navigationBarImage = createImage(color: .clear, size: baseImageSize)
```

## 4. 2と3で生成した画像を合成する

```swift:画像を合成する関数
func composeImage(_ image: UIImage, to baseImage: UIImage, position: CGPoint) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    let baseRect = CGRect(origin: .zero, size: baseImage.size)
    baseImage.draw(in: baseRect)
    let composeRect = CGRect(origin: position, size: image.size)
    image.draw(in: composeRect)
    let composedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return composedImage
}
```

```swift
let composePosition = CGPoint(x: 0, y: UIApplication.shared.statusBarFrame.height)
let composedIamge = composeImage(navigationBarImage, to: baseImage, position: composePosition)
```

## 5. 4で生成した画像をナビゲーションバーの背景画像に設定する

```swift
navigationBar.setBackgroundImage(composedIamge, for: .default)
```

## 6. 完成！

これで完成です。
トータルのコードはこのようになります。

```swift
func createImage(color: UIColor, size: CGSize) -> UIImage {
    let rect = CGRect(origin: .zero, size: size)
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    UIColor.clear.setFill()
    UIRectFill(rect)
    let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return image
}

func composeImage(_ image: UIImage, to baseImage: UIImage, position: CGPoint) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    let baseRect = CGRect(origin: .zero, size: baseImage.size)
    baseImage.draw(in: baseRect)
    let composeRect = CGRect(origin: position, size: image.size)
    image.draw(in: composeRect)
    let composedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return composedImage
}

if let navigationBar = navigationController?.navigationBar {
    navigationBar.tintColor = /* any color */

    let baseImageSize = CGSize(
        widht: UIScreen.main.widht,
        height: navigationBar.frame.height + UIApplication.shared.statusBarFrame.height
    )
    let baseImage = createImage(color: .clear, size: baseImageSize)

    let navigationBarImageSize = CGSize(
        widht: UIScreen.main.widht,
        height: navigationBar.frame.height
    )
    let navigationBarImage = createImage(color: /* any color */, size: baseImageSize)

    let composePosition = CGPoint(x: 0, y: UIApplication.shared.statusBarFrame.height)
    let composedIamge = composeImage(navigationBarImage, to: baseImage, position: composePosition)

    navigationBar.setBackgroundImage(composedIamge, for: .default)
}
```

この方法を利用する利点は、NabigationBarの範囲で色分けが完遂出来るので余計なViewを作ったりすることが無いことです。