Flutter頁面跳轉到IOS原生介面 如何實現?

野生猿James發表於2019-07-12

2019年初的時候,我學過一陣子Flutter,著重看了下Bloc(business logic component),自己寫了個小demo。完了之後,Flutter就被拋之腦後了。

這兩天,有朋友請我幫忙,他們想從Flutter頁面跳轉到IOS原生OC的介面,雖然我不是大神,只是一隻野生的猿,但我喜歡挑戰,答應幫他們看看。說幹就幹,參考了官網的關於編寫跨平臺程式碼文件:傳送門

Flutter頁面跳轉到IOS原生介面   如何實現?

其實基本思路很簡單,兩步

一.Flutter 傳遞訊息給原生,說我要去原生介面

二.在原生AppDelegate.m裡,將FlutterViewController 作為rootViewController,然後放在Navigation Stack裡。當原生接收到訊息,實現跳轉功能,完事!

話不多說,Let's dive in.

第一步,Flutter 怎麼將訊息傳遞到原生端呢?

1.建立一個通訊的頻道

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 Function

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了

platform.invokeMethod('goToNativePage', {'key': 'value'});
複製程式碼

第二步 ,原生接收訊息並實現跳轉

因為你導航到新介面,所以需要引入UINavigationController

在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版本:傳送門

到了這裡,功能就實現了。如果有更好方式,請告訴我.

相關文章