1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FlutterでSwiftUIを呼び出す

Last updated at Posted at 2025-02-15

はじめに

SwiftUIの勉強をしようと思ったのですが、SwiftUIのプロジェクトを作成して勉強進めるより、馴染みのあるFlutterからSwiftUIを呼び出して利用する方が勉強しやすいかなと思い、FlutterからSwiftUIを呼び出す方法を調査しました。

呼び出し方

Flutter側

ネイティブ側の処理を呼び出すコードです。
ボタンのイベントなどから呼び出してください。

import 'package:flutter/services.dart';
Future<void> _showSwiftUIView() async {
  try {
    // ChatGPTに聞いたところ、Channel名には、
    // パッケージ名+用途を表す名前を指定するのが推奨されるようです
    const MethodChannel channel = MethodChannel("com.example.app/view");
    await channel.invokeMethod('showSwiftUIView');
  } on PlatformException catch (e) {
    print("Failed to invoke method: '${e.message}'.");
  }
}

iOS側

ネイティブ側のメソッドを作成

Flutter側から呼び出すiOS側の処理を実装します。

ios/Runner/AppDelegate.swift
import Flutter
import UIKit
+import SwiftUI

@main
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)

+   let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
+   // nameはFlutter側と合わせる必要がある  
+   let methodChannel = FlutterMethodChannel(name: "com.example.app/view", binaryMessenger: controller as! FlutterBinaryMessenger)
+    methodChannel.setMethodCallHandler({
+     (call: FlutterMethodCall, result: FlutterResult) -> Void in
+       switch call.method {
+         case "showSwiftUIView" :
+           // SwiftUIで実装した画面を呼び出す
+           let swiftUIView = SampleView()
+           let hostingController = UIHostingController(rootView: swiftUIView)
+           controller.present(hostingController, animated: true, completion: nil)
+         default :
+           result(nil)
+       }
+   })
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

SwiftUIでUIを作成

Flutter側から呼び出し表示するUIを作成します。

ios/Runner/SampleView.swift
import SwiftUI

struct SampleView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

#Preview {
    SampleView()
}

表示

view1.gif

その他の表示

モーダル表示以外にも画面遷移が可能です

画面遷移

ios/Runner/AppDelegate.swift
import Flutter
import UIKit
+import SwiftUI

@main
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)

    let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
+   // ナビゲーションようにコントローラーを作成
+   let navigationController = UINavigationController(rootViewController: controller)
+   // 透明にしておかないと、Flutter側の画面のAppBar上部が白色となる
+   navigationController.navigationBar.isTranslucent = true
+   navigationController.navigationBar.setBackgroundImage(UIImage(), for: .default)
+   navigationController.navigationBar.shadowImage = UIImage()

+   window = UIWindow(frame: UIScreen.main.bounds)
+   window?.rootViewController = navigationController
+   window?.makeKeyAndVisible()


    
    // nameはFlutter側と合わせる必要がある  
    let methodChannel = FlutterMethodChannel(name: "com.example.app/view", binaryMessenger: controller as! FlutterBinaryMessenger)
     methodChannel.setMethodCallHandler({
      (call: FlutterMethodCall, result: FlutterResult) -> Void in
        switch call.method {
          case "showSwiftUIView" :
            // SwiftUIで実装した画面を呼び出す
            let swiftUIView = SampleView()
            let hostingController = UIHostingController(rootView: swiftUIView)
-           controller.present(hostingController, animated: true, completion: nil)
+           controller.navigationController?.pushViewController(hostingController, animated: true)
          default :
            result(nil)
        }
    })
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?