2019年初的時候,我學過一陣子Flutter,着重看了下Bloc(business logic component),本身寫了個小demo。完了以後,Flutter就被拋之腦後了。git
這兩天,有朋友請我幫忙,他們想從Flutter頁面跳轉到IOS原生OC的界面,雖然我不是大神,只是一隻野生的猿,但我喜歡挑戰,答應幫他們看看。說幹就幹,參考了官網的關於編寫跨平臺代碼文檔:傳送門 github
其實基本思路很簡單,兩步swift
一.Flutter 傳遞消息給原生,說我要去原生界面bash
二.在原生AppDelegate.m裏,將FlutterViewController 做爲rootViewController,而後放在Navigation Stack裏。當原生接收到消息,實現跳轉功能,完事!async
話很少說,Let's dive in.ide
1.建立一個通訊的頻道ui
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
...
class _MyHomePageState extends State<MyHomePage> {
static const platform = const MethodChannel('samples.flutter.dev/goToNativePage');
}
複製代碼
2.實現Trigger Functionatom
Future<void> _goToNativePage() async {
try {
final int result = await platform
.invokeMethod('goToNativePage', {'test': 'from flutter'});
print(result);
} on PlatformException catch (e) {}
}
@override
Widget build(BuildContext context) {
return Material(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RaisedButton(
child: Text('去原生界面'),
onPressed: _goToNativePage,
color: Colors.blueAccent,
textColor: Colors.white,
),
Text(
"Flutter 頁面",
style: new TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.w900,
fontFamily: "Georgia",
),
)
],
),
),
);
}
複製代碼
添加一個按鈕,給這按鈕再添加一個_goToNativePage方法,在這裏若是還要傳遞參數的話,直接像這樣寫就ok了spa
platform.invokeMethod('goToNativePage', {'key': 'value'});
複製代碼
由於你導航到新界面,因此須要引入UINavigationController
code
在AppDelegate.m裏,@implementation AppDelegate
上方添加代碼
@interface AppDelegate()
@property (nonatomic, strong) UINavigationController *navigationController;
@end
複製代碼
1.將FlutterView設爲根視圖
FlutterViewController *controller = (FlutterViewController*)self.window.rootViewController;
複製代碼
2.嵌入導航堆棧裏
self.navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = self.navigationController;
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self.window makeKeyAndVisible];
複製代碼
3.Flutter和原生通訊的接口的實現
FlutterMethodChannel* testChannel =
[
FlutterMethodChannel methodChannelWithName:@"samples.flutter.dev/goToNativePage"
binaryMessenger:controller
];
[testChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
NSLog(@"%@", call.method);
//接收從flutter傳遞過來的參數
NSLog(@"%@", call.arguments[@"test"]);
if ([@"goToNativePage" isEqualToString:call.method]) {
//實現跳轉的代碼
} else {
result(FlutterMethodNotImplemented);
}
}];
複製代碼
想獲取從flutter傳遞過來的參數, call.arguments[@"key"]
,用這段代碼
4.實現跳轉到原生界面
到了這,就至關簡單了,補全跳轉代碼
NSString * storyboardName = @"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"NativeViewController"];
vc.navigationItem.title = call.arguments[@"test"];
[self.navigationController pushViewController:vc animated:true];
複製代碼
gayhub 項目地址:傳送門
IOS Swift版本:傳送門
到了這裏,功能就實現了。若是有更好方式,請告訴我.