mrgnhnt96
mrgnhnt96

Reputation: 3945

How to add a FlutterViewController to a UIViewController

All the documentation that I can find for Flutter's Add-to-App demonstrates how to push/segue/present a newly created FlutterViewController. I need to add a flutter view to a tab within a tabbar. I tried changing my class's super class from UIViewController to FlutterViewController which worked, but is not using the flutter engine that is created within the app delegate. This solution resulted in showing in the launch screen before the flutter view, which isn't desired.

How do I add a flutter view to a UIViewController? Or how do I assign an engine to a FlutterViewController from within the class?

Upvotes: 2

Views: 3894

Answers (3)

psychic_coder
psychic_coder

Reputation: 31

The current answer is accurate, but one thing to point out if you run into the same issue as me where the Flutter view appears only if you press Home and then come back to it is that you need to make sure you're adding the correct Flutter.xcframework file.

I was incorrectly adding the Flutter.xcframework file from the following path:

<path_to_flutter_sdk>/bin/cache/artifacts/engine/ios/Flutter.xcframework

Instead of

<path_to_flutter_sdk>/bin/cache/artifacts/engine/ios/extension_safe/Flutter.xcframework

The key being that you need to make sure you get the Flutter.xcframework file from within the extension_safe directory.

After updating that everything worked correctly.

Note: I followed this tutorial https://docs.flutter.dev/platform-integration/ios/app-extensions

Upvotes: 0

Aman Singh
Aman Singh

Reputation: 1

// create an extension for all UIViewControllers
extension UIViewController {
     /**
         Add a flutter sub view to the UIViewController
         sets constraints to edge to edge, covering all components on the screen
     */
    func addFlutterView(with engine: FlutterEngine) {
        // create the flutter view controller
        let flutterViewController = FlutterViewController(engine: engine, nibName: nil, bundle: nil)
        
        addChild(flutterViewController)
        
        guard let flutterView = flutterViewController.view else { return }

        // allows constraint manipulation
        flutterView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(flutterView)
        
        // set the constraints (edge-to-edge) to the flutter view
        let constraints = [
            flutterView.topAnchor.constraint(equalTo: view.topAnchor),
            flutterView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            flutterView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            flutterView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ]

        // apply (activate) the constraints
        NSLayoutConstraint.activate(constraints)

        flutterViewController.didMove(toParent: self)
        
        // updates the view with configured layout
        flutterView.layoutIfNeeded()
    }
}

with any UIViewController, you can add a flutter subview now.

@IBAction func  loadFlutterView(){
   flutterEngine.run(withEntrypoint: nil, libraryURI: nil, initialRoute: nil, entrypointArgs: [ "CONSENT_HANDLE=\(conentHandle)","PACKAGE_NAME=com.pirimid.fiu"]);
            GeneratedPluginRegistrant.register(with: self.flutterEngine);
            addFlutterView(with: flutterEngine)
}

Upvotes: 0

mrgnhnt96
mrgnhnt96

Reputation: 3945

I found a solution which adds the flutter view to the view controller.

// create an extension for all UIViewControllers
extension UIViewController {
     /**
         Add a flutter sub view to the UIViewController
         sets constraints to edge to edge, covering all components on the screen
     */
    func addFlutterView(with engine: FlutterEngine) {
        // create the flutter view controller
        let flutterViewController = FlutterViewController(engine: engine, nibName: nil, bundle: nil)
        
        addChild(flutterViewController)
        
        guard let flutterView = flutterViewController.view else { return }

        // allows constraint manipulation
        flutterView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(flutterView)
        
        // set the constraints (edge-to-edge) to the flutter view
        let constraints = [
            flutterView.topAnchor.constraint(equalTo: view.topAnchor),
            flutterView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            flutterView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            flutterView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ]

        // apply (activate) the constraints
        NSLayoutConstraint.activate(constraints)

        flutterViewController.didMove(toParent: self)
        
        // updates the view with configured layout
        flutterView.layoutIfNeeded()
    }
}

with any UIViewController, you can add a flutter subview now.

override func viewDidLoad() {
    super.viewDidLoad()
    
    // get the flutter engine for the view
    let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
    
    // add flutter view
    addFlutterView(with: flutterEngine)

    // Do any additional setup after loading the view.
}

Upvotes: 8

Related Questions