新建一个iOS项目Test
在iOS同级目录下建一个flutter module
flutter create --template module my_flutter
podfile编写如下
# Uncomment the next line to define a global platform for your project # platform :ios, '9.0' target 'Test' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! flutter_application_path = '../my_flutter' load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') install_all_flutter_pods(flutter_application_path) # Pods for Test end post_install do |installer| flutter_post_install(installer) if defined?(flutter_post_install) end
使用
- 直接使用
-
navigationController?.pushViewController(FlutterViewController(), animated: true)
- 有交互的使用
-
import UIKit import Flutter // The following library connects plugins with iOS platform code to this app. //import FlutterPluginRegistrant @UIApplicationMain class AppDelegate: FlutterAppDelegate { // More on the FlutterAppDelegate. let engines = FlutterEngineGroup(name: "ios_fultter_double", project: nil) override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Runs the default Dart entrypoint with a default Flutter route. // flutterEngine.run(); // Connects plugins with iOS platform code to this app. // GeneratedPluginRegistrant.register(with: self.flutterEngine); return super.application(application, didFinishLaunchingWithOptions: launchOptions); } } // Copyright 2021 The Flutter team. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import Flutter import FlutterPluginRegistrant import Foundation /// A FlutterViewController intended for the MyApp widget in the Flutter module. /// /// This view controller maintains a connection to the Flutter instance and syncs it with the /// datamodel. In practice you should override the other init methods or switch to composition /// instead of inheritence. class InteractionViewController: FlutterViewController { private var channel: FlutterMethodChannel? init(withEntrypoint entryPoint: String?) { let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate let newEngine = appDelegate.engines.makeEngine(withEntrypoint: entryPoint, libraryURI: nil) GeneratedPluginRegistrant.register(with: newEngine) super.init(engine: newEngine, nibName: nil, bundle: nil) } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() channel = FlutterMethodChannel( name: "ios_fultter_double", binaryMessenger: engine!.binaryMessenger) let navController = navigationController! channel!.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in if call.method == "incrementCount" { result(nil) } else if call.method == "next" { navController.pushViewController(FlutterViewController(), animated: true) result(nil) } else { result(FlutterMethodNotImplemented) } } } }
// Copyright 2021 The Flutter team. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() => runApp(const MyApp(color: Colors.blue)); @pragma('vm:entry-point') void topMain() => runApp(const MyApp(color: Colors.green)); @pragma('vm:entry-point') void bottomMain() => runApp(const MyApp(color: Colors.purple)); class MyApp extends StatelessWidget { const MyApp({super.key, required this.color}); final MaterialColor color; @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorSchemeSeed: color, useMaterial3: true, appBarTheme: AppBarTheme( backgroundColor: color, foregroundColor: Colors.white, elevation: 8, ), ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int? _counter = 0; late MethodChannel _channel; @override void initState() { super.initState(); _channel = const MethodChannel('ios_fultter_double'); _channel.setMethodCallHandler((call) async { if (call.method == "setCount") { // A notification that the host platform's data model has been updated. setState(() { _counter = call.arguments as int?; }); } else { throw Exception('not implemented ${call.method}'); } }); } void _incrementCounter() { // Mutations to the data model are forwarded to the host platform. _channel.invokeMethod<void>("incrementCount", _counter); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), TextButton( onPressed: _incrementCounter, child: const Text('Add'), ), TextButton( onPressed: () { _channel.invokeMethod<void>("next", _counter); }, child: const Text('Next'), ), ElevatedButton( onPressed: () async { // Use the url_launcher plugin to open the Flutter docs in // a browser. final url = Uri.parse('https://flutter.dev/docs'); }, child: const Text('Open Flutter Doc11s'), ), ], ), ), ); } }