iOS14でイメージピッカーが部分的に透ける問題とその解決方法

公開:2020/10/07
更新:2020/10/07
3 min読了の目安(約2900字TECH技術記事

前提

iOS14のイメージピッカーについて

iOS14でイメージピッカーのUIが変わりました[1]

このUIはiOS14で追加されたPHPickerViewControllerだけではなく、既存のUIImagePickerControllerにも反映されています。

UINavigationBarの見た目をカスタマイズする

UINavigationBarの背景を透過させたり線を消すためのハック[2]があります。

UINavigationBar.appearance().isTranslucent = false
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)

問題

先述のハックを適用した状態でPHPickerViewControllerまたはUIImagePickerControllerを開くと、↓の画像のように検索エリアが透けてしまいます。

解決方法

UINavigationBar.appearance()が影響しているため、イメージピッカーを表示する瞬間だけUINavigationBar.appearance().backgroundImageの設定をリセットしてあげれば良さそうです。

PHPickerViewControllerの場合

var configuration = PHPickerConfiguration()
configuration.selectionLimit = 1
configuration.filter = .images

let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self

// 表示する直前にリセットする
UINavigationBar.appearance().setBackgroundImage(nil, for: .default)

present(picker, animated: true) {
    // 表示した後に元に戻す
    UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
}

UIImagePickerControllerの場合

let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
picker.allowsEditing = true

// 表示する直前にリセットする
UINavigationBar.appearance().setBackgroundImage(nil, for: .default)

present(picker, animated: true) {
    // 表示した後に元に戻す
    UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
}

結果

↓のようにイメージピッカーの検索エリアが透けずに表示されるようになりました🎉

ちなみに、UINavigationBar.appearance().isTranslucentUINavigationBar.appearance().shadowImageもリセットするとデフォルトのような表示になります。

// (前略)

// 表示する直前にリセットする
UINavigationBar.appearance().isTranslucent = true
UINavigationBar.appearance().shadowImage = nil
UINavigationBar.appearance().setBackgroundImage(nil, for: .default)

present(picker, animated: true) {
    // 表示した後に元に戻す
    UINavigationBar.appearance().isTranslucent = false
    UINavigationBar.appearance().shadowImage = UIImage()
    UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
}

よもやま話

元々はUIImagePickerControllerを使っている画面で発覚した現象でした。
PHPickerViewControllerを使えよ」っていうお上のお告げかと思いきや...😇

最後に

UINavigationBarの見た目をカスタマイズしているアプリに関わっている方はイメージピッカー周りにご注意ください。

脚注
  1. 参考: The New Photos Picker in iOS 14 - Part 1 ↩︎

  2. 参考:UINavigationBar・UITabBar のカスタマイズ方法について#ナビバーの背景を透過させる・下線を消す ↩︎