【Flutter】iOS の PlatformView を利用する

Flutter

Flutter で iOS側のビューを表示した場合、全てのビューが Flutter の画面よりも上に表示されてしまいます。

PlatformView を使えばビューが Flutter のウイジェットツリーに組み込まれるので、表示の階層やレイアウトが Flutter 側で制御できるようになり、取り回しが大変良くなります。

ここでは PlatformView の iOS側の実装と、Flutter 側で PlatformView を利用する方法について解説します。

スポンサーリンク

iOS 側の実装

Info.plist にキーを追加

iOS/Runner/Info.plist に以下のキーを追加します。

<key>io.flutter.embedded_views_preview</key>
<true/>

PlatformView とビュー生成用のクラスを定義

PlatformView を生成するクラスと実際のビューとなるクラスを定義します。(Swift)

// PlatformView を生成するクラス
class MyFlutterPlatformViewFactory: NSObject, FlutterPlatformViewFactory {
  func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
    return MyView(frame: frame, arguments:args)
  }
}

// PlatformView クラス
class MyView: NSObject, FlutterPlatformView {
  let _view = UIView() // 実際のビュー

  // 初期化
  init(frame: CGRect, arguments: Any?) {
    super.init()
    _view.frame = frame
    _view.backgroundColor = .blue
  }

  // ここで実際のビューを返します
  func view() -> UIView {
    return _view
  }
}

PlatformView をプラグインとして登録

AppDelegate.swift に PlatformView をプラグインとして登録するコード(Swift)を書きます。

let viewFactory = MyFlutterPlatformViewFactory()
registrar(forPlugin: "MyView").register(viewFactory, withId: "my_platform_view")

“my_platform_view” はビューの一意の識別子です。このIDを Flutter 側の呼び出し時に使います。

“MyView” は任意のプラグイン名です。PlatformView はプラグインとして利用する仕組みになっているためこのような手続きになっています。

Flutter 側で PlatformView を表示する

Flutter 側で PlatformView を表示する場合は、UiKitView ウィジェットを使います。

UiKitView(viewType: 'my_platform_view'),

viewType: にiOS 側で宣言した一意の識別子を指定します。

Flutter 公式によると、PlatformView は Flutter に相当するものがある場合は避ける必要があり、多用は好ましくないとされています。あまり込み入った用途での使用は避けるのが良いかもですね。

Flutter 側のサンプルコード

Flutter 側のサンプルコードです。(iOS側の実装は前述のコードをコピペしてお試しください)

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

// MyApp ウィジェットクラス
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light(),
      home: MyHomePage(title: 'FlutterPlatformView'),
    );
  }
}

// MyHomePage ウィジェットクラス
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

// MyHomePage ステートクラス
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('PlatformView'),
            // コンテナで囲ってサイズを調整
            Container(
              width: 200,
              height: 200,
              child: UiKitView(viewType: 'my_platform_view'), // ←ココ
            ),
          ],
        ),
      ),
    );
  }
}

PlatformView を使う場合は、Flutter と iOS で相互にやり取りできると色々便利なので、以下の記事も参考にしてみてください。

コメント

タイトルとURLをコピーしました