👻

Flutter on iOS で rootViewController を変更する

2020/10/01に公開

※この記事は Flutter v0.7.3 をもとにして書かれています

Flutter の iOS 向けの実装で、標準では FlutterViewController が rootViewController となっています。Flutter だけでアプリのすべてを実装できる場合は問題ありませんが、ネイティブの ViewController と連携する場合に rootViewController を違うものにしたい場合があります。例えば CARTUNE では root には UINavigationController を設定し、その最初の画面として FlutterViewController を使っています。

まず ios/Runner/Info.plistUIMainStoryboardFile の項目を削除し、使わなくなった ios/Runner/Base.lproj/Main.storyboard も削除しておきます。

続いて AppDelegate の起動時の処理 override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool でコードから rootViewController を設定するようにします。

@objc class AppDelegate: FlutterAppDelegate {
    var flutterViewController: FlutterViewController?

    ...
self.flutterViewController = FlutterViewController()
let nav = UINavigationController.init(rootViewController: self.flutterViewController!)
self.window.rootViewController = nav
self.window.makeKeyAndVisible()

あとは、いくつかのメソッドをオーバーライドします。Flutter の標準の実装では rootViewController が FlutterViewController である前提となっていますので、オーバーライドしてメソッド呼び出しが Flutter へ伝わるようにします。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesBegan(touches, with: event)
    
    // rootがFlutterViewControllerの場合はsuper.touchesBeganだけでよいのでreturn
    if let vc = UIApplication.shared.keyWindow?.rootViewController as? FlutterViewController {
        return
    }
    
    // そうでない場合はFlutterViewControllerに対してhandleStatusBarTouchesを呼ぶ
    self.flutterViewController?.handleStatusBarTouches(event)
}

override func registrar(forPlugin: String) -> FlutterPluginRegistrar {
    return (self.flutterViewController?.registrar(forPlugin: forPlugin))!
}

override func hasPlugin(_ pluginKey: String) -> Bool {
    return (self.flutterViewController?.hasPlugin(pluginKey))!
}

override func valuePublished(byPlugin pluginKey: String) -> NSObject {
    return (self.flutterViewController?.valuePublished(byPlugin: pluginKey))!
}

この記事はQiitaの記事をエクスポートしたものです

Discussion