iOS15でPHPickerのNavigationBarの色を変更する

# 結論
iOS15でPHPickerのNavigationBarの色を変更するのはおすすめしない。

Apple Developer Forumsに「どう変更するのか」と質問すると、AppleのFrameworks　Engineerの方から以下の回答が返ってきた。
> PHPicker is out of process and currently doesn't support any UI customization, other than inheriting your application's tint color.
We recommend just using the default system picker UI. Most users already used PHPicker in other apps, and familiarity could help them trusting your app.
However, please submit an enhancement request via the Feedback app, if you think your app needs specific customization options.
https://developer.apple.com/forums/thread/701712

要約すると「PHPickerではUIのカスタマイズをサポートしてない。デフォルトのUIを使用することを勧める。」とのこと。
というわけで、iOS15ではNavigationBarの色を変えずにデフォルトのUIのままにした方がよさそう。

# iOS15でNavigationBarの色を変更しようとするとどうなるか？
まず、iOS15からNavigationBarの色をカスタマイズするには、以下のようにAppearanceで設定する必要がある。
```swift
    if #available(iOS 15, *) {
        let navigationBarAppearance = UINavigationBarAppearance()
        // NavigationBarを不透明な状態にする
        navigationBarAppearance.configureWithOpaqueBackground()
        // アプリ内全てのNavigationBarの背景色を赤に設定
        navigationBarAppearance.backgroundColor = .red
        UINavigationBar.appearance().standardAppearance = navigationBarAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance
        UINavigationBar.appearance().compactAppearance = navigationBarAppearance
    } else {
        // iOS14以下の場合はbarTIntColorで背景色を設定する
        UINavigationBar.appearance().barTintColor = .red
    }
```
上記コードをAppDelegate.swiftなどで適用すると、以下のようにアプリ全体でNavigationBarが赤くなる

|iOS15|iOS14|
|--|--|
|![simulator_screenshot_6EB72662-A974-4D0D-BB97-DEE9650E6F2A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/5c3a7d8e-591a-8d37-5b71-3b459a432104.png)|![simulator_screenshot_D05F2E3A-4412-4852-89E2-CDA7A47A60A7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/0dfcb129-fd91-8667-6047-ee2731922d24.png)|

（若干iOS14の方が色が薄いのも気になる）
この状態でPHPickerを開くと、期待値としてはPHPickerのNavigationBarにも赤色が付与されることであるが...
|iOS15|iOS14|
|--|--|
|![simulator_screenshot_E763D88E-D162-42E5-8AB1-03179D49B022.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/b76c6c8b-43e6-2dba-2257-018c4f3d04f2.png)|![simulator_screenshot_7D11C069-6701-4357-BCDE-93F1F6CB038A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/9e81b0b9-7bd2-7167-d1e6-d8b78b731b6d.png)|

iOS15ではデフォルトの色のまま表示されてしまう。
iOS14では問題なく赤色が適用されている。

どうやらiOS15からは今まで通りのような方法では変更できなさそう。

# それでも色を変更したい...！
どうしてもPHPickerの色を変更したい場合、以下の方法がある
変更したい色を画像として出力し、NavigationBarに貼り付ける方法である。
```swift
    let navigationBarHeight = UINavigationController().navigationBar.frame.height
    let size = CGSize(width: UIScreen.main.bounds.width, height: navigationBarHeight)
    let renderer = UIGraphicsImageRenderer(size: size)
    let image = renderer.image { context in
        // 画像を赤で塗る
        UIColor.red.setFill()
        context.fill(context.format.bounds)
    }
    UINavigationBar.appearance().setBackgroundImage(image, for: .default)
```
上記コードを適用すると

|シミュレータ|実機|
|--|--|
|![simulator_screenshot_9A05D57B-6149-45F8-85B3-9837BFE17526.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/05abae1f-570d-f729-e503-2480afcfc631.png)|![IMG_5515.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/9c2c13e3-c530-14b2-eb23-f2906984d118.png)|

ん？シミュレータではいい感じに適用されていて問題なさそうだが、実機ではSearchBarが表示されているぞ...？　しかも色が適用されてない。
そう。不具合なのか不明だが、シミュレータでPHPickerを開いた時にはなぜかSearchBarが表示されないようだ。

一応この状態でも、SearchBarをタップすることでSearchBarにも色が適用されるようになっている。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/fd940282-39d8-e165-6319-53a06465cfd1.gif" width="300">

SearchBarをタップしなくてもPHPickerを開いた時に既に色が適用されているように変更してみる
アプリ全体のSearchBarの背景色を変えることで実現できる

```swift
    UISearchBar.appearance().backgroundColor = .red
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/26108e2a-4196-eba3-721a-008be2eb0a5c.gif" width="300">

ぱっと見は問題なさそうだが、色を画像として貼り付けてた影響により、NavigationBarが半透明な状態になってしまっている。
SearchBarは不透明なため、よくみると違和感がある。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/1af8bc8e-9b12-2036-8056-d8201cd8f84c.png" width="300">

これを回避するために、`UINavigationBar.appearance()`自体に`.backgroundColor`を設定することで不透明にできる。（なぜこうなるのかは不明）
```swift
    UINavigationBar.appearance().backgroundColor = .red
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/56dcc0a0-d0d8-9643-b93e-4ccdf2cdf8b6.png" width="300">

以上でPHPickerの背景色を変更することはできる。

# NavigationBarItemの色の変更
iOS15のPHPickerでも「キャンセル」「追加」などのNavigationBarItemの色自体は従来の方法で変更できる。
```swift
    UIBarButtonItem.appearance().tintColor = .green
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/846b7dc3-aafa-24b3-2b8c-0d1cc696c803.png" width="300">

# まとめ
冒頭の結論の通り、iOS15ではPHPickerのNavigationBarの色を変更するのはお勧めしない。
紹介した通りのトリッキーな方法でなんとか色をつけることもできるが、Apple的にはデフォルトのUIのままPHPickerを使用してほしいからである。
iOS15でUIのカスタマイズをサポートしてないのであれば、今後登場するであろうiOS16以降でも同様にサポートしない気がする
これは憶測になるが、iOS15からAppleはかなりプライバシー周りのことを強化しているイメージがあり、PHPickerも写真という個人情報満載の画面を提供するViewControllerなため、Apple的には開発者側があまりPHPickerに介入できないようにしているんじゃないかと思う