首页 > 解决方案 > 如何通过 Flutter Method Channel 在 Flutter 中使用导航控制器调用 Swift 视图控制器

问题描述

我正在尝试通过我在 AppDelegate.swift 文件中定义的名为“callNavigator()”的私有函数调用我在名为“MainNavigationController.swift”的单独文件中定义的 UINavigationController 我正在通过 Flutter 端调用该方法成功发回消息的方法通道正在发生一些通信“Flutter/Dart 端没有问题”。我希望该功能使用“MainNavigationController.swift”中定义的导航器将视图推送到颤振屏幕顶部。我的 MainNavigationController.swift 中的代码如下:

import Foundation
    import UIKit

    class MainNavigationController: UINavigationController{
        override func viewDidLoad() {
            super.viewDidLoad()
        }
        private func navigateToMainInterface() {
            let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
           guard let mainNavigationVc = mainStoryboard.instantiateViewController(withIdentifier:"MainNavigationController") as? MainNavigationController else {
                return

            }
            present(mainNavigationVc, animated: true, completion: nil)

        }
    }
Then I am trying to call this class in my "AppDelegate.swift file" through my "callNavigator()" private function as a constructor. The code is as follows in the Appdelegate.swift file :


    @UIApplicationMain
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?

      ) -> Bool {
        let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
        GeneratedPluginRegistrant.register(with: self)      

        let navigatorChannel = FlutterMethodChannel(name: "com.fluttertonative/navigateToCameraSDK", binaryMessenger:  controller.binaryMessenger)
       navigatorChannel.setMethodCallHandler ({
          [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
          // Note: this method is invoked on the UI thread.
          guard call.method == "getSwiftNavigator" else {
            result(FlutterMethodNotImplemented)
            return
          }
          self?.callNavigator()

       })
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
        private func receiveGreeting(result: FlutterResult){
            result("Hello from Swift Code...")
        }
        private func callNavigator(){
            MainNavigationController()

        }
    }

但是,我在 Xcode 中收到警告,试图调用“MainNavigationController”的“callNavigator”函数没有使用其结果,它说“'UINavigationController' 初始化程序的结果未使用”。我是 swift 新手,我不知道该怎么做。

我已将 Initial navigator 设置为我的 Main.storyBoard 中的 FlutterViewController,我在其中放置了一些虚拟文本文件。当我从 Flutter 端调用方法通道时,我想要运行“callNavigator”函数,该函数又调用“MainNavigationController.swift”文件中的“MainNavigationController”,它应该在视图顶部推送一个新视图颤动的屏幕。

我需要一些帮助来实现这一点,因为我是 Swift 语言的新手

那么我的飞镖代码如下:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const navigateToCameraSDK = const MethodChannel('com.fluttertonative/navigateToCameraSDK');

  String _greeting = 'awaiting swift call..';


  Future _getnavigator() async{
    try {
      final result = navigateToCameraSDK.invokeMapMethod('getSwiftNavigator');
      print(result);
    } on PlatformException catch (e){
      print('error:$e');
      _greeting = 'error occured:$e';
    }
    setState(() {
      _greeting ='call successful you have got the swift Navigator';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Container(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Text(_greeting),
              CupertinoButton(
                child: Text('call swift to get the navigator'),
                onPressed: _getnavigator,
                borderRadius:BorderRadius.all(Radius.circular(13.0)),
                color: Colors.blue[300],
              ),
            ],
          ),
        ));
  }
}

而我的故事板如下——Flutter View Controller 是最初的 View Controller。在此处输入图像描述: 在此处输入图像描述

标签: flutterflutter-dependencies

解决方案


默认情况下,Flutter iOS 应用程序没有UINavigationViewController. 这是将视图控制器推送到导航堆栈所必需的。

AppDelegate不过,通过类添加它很容易。


import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    
    var navigationController: UINavigationController!
    
    override func application(_ application: UIApplication,
                            didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
      
      
        let controller = window?.rootViewController as! FlutterViewController
        GeneratedPluginRegistrant.register(with: self)
        
        // create and then add a new UINavigationController
        self.navigationController = UINavigationController(rootViewController: controller)
        self.window.rootViewController = self.navigationController
        self.navigationController.setNavigationBarHidden(true, animated: false)
        self.window.makeKeyAndVisible()
        
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

}

稍后,当您将FlutterMethodChannel添加到您的应用程序委托时,您可以UIViewController以标准 iOS 方式简单地推送/显示一个新的。

    // called from within the FlutterMethodChannel handler
    private func pushViewController() {
        //get view controller from StoryBoard, XIB or in code
        let vc = ...       
        self.navigationController.setNavigationBarHidden(false, animated: true)
        self.navigationController.pushViewController(vc, animated: true)
    }

推荐阅读