Objective-C
iOS
Swift

【Swift】SFSafariViewControllerが白くなる?

SFSafariViewControllerが読み込まれない

同様の問題
https://stackoverflow.com/questions/45641887/sfsafariviewcontroller-displays-empty-screen-for-any-url
スクリーンショット 2017-10-01 23.31.39.png

上図のようにSFSafariViewControllerが白くなってしまう場合があったので原因を調べて見ました。

実行したソース

let url = URL(string: "https://qiita.com/0905Tom")
let viewController = SFSafariViewController(url: url!)
topVC?.present(viewController, animated: true)

何気ないこのソースでSFSafariViewControllerが白くなってしまいました。
なぜだろうと思い少し調査していると、どうやらUIApplication.shared.keyWindowに問題がある様子。

私が実現したかったのはYoutubeのように右下にPlayerを表示したまま、SFSafariViewControllerにpresentという動作。
そのため、presentする前に自作UIWindow.rootViewControllerに対してPlayerViewControllerをセットし、window?.makeKeyAndVisible()をしていました。そうすると元keyWindow、つまりkeyWindow上にないtopVCからpresentすることでこのように白くなりました。

解決方法

幸いWindowManager的なもので複数のwindowを管理していたため、以下のように対応することで期待する動作をしました。

※以下はソースの抜粋です!!

// 複数のUIWindowを管理しているクラス
class WindowManager {
  static let shared = WindowManager()

  var topWindow: UIWindow?

  var topVC: UIViewController? {
    return topWindow?.rootViewController
  }

  var playerWindow: UIWindow?
}

// SFSafariViewControllerに遷移するメソッド
func presentToSafari() {
  let url = URL(string: "https://qiita.com/0905Tom")
  let viewController = SFSafariViewController(url: url!)
  WindowManager.shared.topWindow.makeKey()
  WindowManager.shared.topVC?.present(viewController, animated: true)
}

少し乱雑になってしまいましたがイメージは上記の感じです。サンプルリポジトリは後日作ろうと思います。
present元にしたいUIWindowに対して再度makeKey()してあげると正常に表示されました!
PlayerViewControllerもきちんとSFSafariViewControlller上で動作しました。

最後に

対応の仕方はそのプロジェクトの構成によりけりですがSFSafariViewControllerはkeyWindowからの遷移を想定している様です...何か他の解決法を見つけた方、同様の問題が起きたことがある方がいらっしゃいましたらご教授お願いします :bow: