讓我們探索如何将 Flutter 視圖添加到 iOS 原生視圖(如 UIViewController)中。
今天,我們将在 iOS 中實作一個簡單的示範應用程式,它将有兩個 Flutter 頁面,在第一個頁面上,我們将顯示使用者清單,第二個螢幕将是使用者詳細資訊螢幕。
我們将把 Flutter 子產品作為包庫嵌入到我們的原生 iOS 應用程式中。
為了便于了解,我将文章分為 4 個邏輯步驟。
- 建立 Flutter 子產品
- 從子產品生成 iOS 架構
- 将架構內建和嵌入到本機應用程式中
- 作為 UIViewController 打開顫動視圖
好吧,讓我們開始吧!
1.建立一個Flutter子產品
首先,如果您尚未在系統上安裝 Flutter SDK,那麼現在是安裝的好時機。繼續并按照此連結查找在您的機器上設定顫振的說明。
可以了,好了?偉大的 !!!
讓我們首先從現有的 Flutter 項目建立 Flutter 子產品。
從指令行界面,導航到您希望在 Flutter 項目中儲存 Flutter 子產品的目錄,然後使用 Flutter CLI 工具運作以下指令:
flutter create -template module --org com.demo flutter_lib
此指令将建立一個帶有 .android 和 .ios 隐藏檔案夾的顫振子產品。這些檔案夾是自動生成的,是以不要進行任何更改。
然後在flutter_lib目錄下運作flutter pub get。
我們完成了設定。現在讓我們在子產品的 main.dart 中添加一個螢幕。
我們不打算介紹 Flutter 的實作。
這是我們的顫振子產品應用程式。完整的源代碼可在 GitHub 上找到。您可以将其從此處複制到您的 dart 檔案中。
最後,我們将擁有一個像下面這樣的應用程式。
2.從子產品生成iOS架構
現在,讓我們開始将 Flutter 子產品內建到我們的原生 iOS 應用程式中。
在 flutter_lib/lib 中的 main.dart 檔案中,我們已經定義了從 Native 子產品調用的入口點函數。
入口點函數是這樣的,
@pragma("vm:entry-point")
void nativeLoad() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
此函數将從 iOS 應用程式調用。 是以,調用此函數時啟動的任何 View 都将內建到 iOS 應用程式中。 我們将在下面進一步看到它的使用。
現在讓我們從 Flutter 子產品生成 iOS 架構。
根據 Flutter 文檔,我們有很多方法可以建立 iOS 架構并将其嵌入到原生項目中,但這裡我們将使用其第二個選項,即 Xcode 中的 Embed frameworks。
讓我們首先生成一個 iOS 架構。 從 flutter_lib 目錄運作此指令。
flutter build ios-framework
它将建立 3 個單獨的架構目錄,如下所示。
some/path/MyApp/flutter_lib/build/ios
└── Flutter/
├── Debug/
│ ├── Flutter.xcframework
│ ├── App.xcframework
│ ├── FlutterPluginRegistrant.xcframework (only if you have plugins with iOS platform code)
│ └── example_plugin.xcframework (each plugin is a separate framework)
├── Profile/
│ ├── Flutter.xcframework
│ ├── App.xcframework
│ ├── FlutterPluginRegistrant.xcframework
│ └── example_plugin.xcframework
└── Release/
├── Flutter.xcframework
├── App.xcframework
├── FlutterPluginRegistrant.xcframework
└── example_plugin.xcframework
如果您隻想生成特定的單一建構類型,那麼它也是可能的。
假設我們隻想為調試應用程式生成一個架構,那麼指令将是這樣的,
flutter build ios-framework --no-release --no-profile
或者
flutter build ios-framework --debug
完畢? 現在,讓我們繼續吧。
3. 将架構內建并嵌入到原生應用程式中
生成的動态架構必須嵌入到您的應用程式中才能在運作時加載。
我們隻需将架構拖放到 iOS 項目的根目錄中即可嵌入架構。
它看起來像這樣,
現在我們必須檢查所有添加的架構是否都嵌入到項目中。
為此,導航到目标的 Build Settings > General > Frameworks、Libraries 和 Embedded Content 部分,然後從下拉清單中選擇 Embed & Sign 以添加架構。
但是,這還不夠,我們還必須給出添加架構目錄的搜尋路徑。
在目标的建構設定中,将“$(SRCROOT)/Debug”添加到架構搜尋路徑 (FRAMEWORK_SEARCH_PATHS),或者您可以簡單地将目錄拖放到該選項的值部分。
而已。 您現在應該能夠建構項目而不會出現任何錯誤。
4.打開flutter view為UIViewController
要從現有的 iOS 啟動 Flutter 螢幕,我們必須使用 FlutterEngine 和 FlutterViewController 類。
根據 Flutter Doc,-
FlutterEngine 充當 Dart VM 和 Flutter 運作時的宿主,FlutterViewController 附加到 FlutterEngine 以将 UIKit 輸入事件傳遞給 Flutter 并顯示由 FlutterEngine 渲染的幀。
讓我們首先在主 viewController 中添加一個簡單的按鈕,這樣我們就可以通過單擊該按鈕來打開 Flutter 視圖。
現在讓我們看看如何打開顫振視圖。
a。 建立 FlutterEngine
讓我們首先修改 AppDelegate.swift 檔案以進行所需的更改。
import UIKit
import Flutter
// Used to connect plugins (only if you have plugins with iOS platform code).
// import FlutterPluginRegistrant
@UIApplicationMain
class AppDelegate: FlutterAppDelegate { // More on the FlutterAppDelegate.
lazy var flutterEngine = FlutterEngine(name: "my flutter engine")
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Runs the default Dart entrypoint with a default Flutter route.
flutterEngine.run(withEntrypoint: "nativeLoad", libraryURI: "package:flutter_lib/main.dart")
// Used to connect plugins (only if you have plugins with iOS platform code).
// GeneratedPluginRegistrant.register(with: self.flutterEngine);
return super.application(application, didFinishLaunchingWithOptions: launchOptions);
}
}
在這裡,我們做了以下更改——
- 根據 Flutter 的要求,我們必須遵守 AppDelegate 類中的 FlutterAppDelegate 協定。
- 之後,我們建立了一個 FlutterEngine 類的執行個體,name 參數可以是任何你喜歡的!
- 在這個項目中,我們隻打開了一個 Flutter 視圖,是以我們隻添加了一個 FlutterEngine,但是如果您必須打開多個 Flutter 視圖,則必須相應地建立單獨的引擎。
-
之後,我們添加了一個flutter run語句,這裡用于參數-withEntrypoint:我們必須傳遞我們在flutter子產品的main.dart檔案中配置的entryPoint函數名稱。
libraryURI:傳遞子產品的 dart 檔案路徑。否則,它隻會打開一個空的模糊螢幕。
我們必須使用 package: 關鍵字來傳遞 dart 檔案位置,否則在少數情況下将無法正常工作。
b。作為 UIViewController 打開 Flutter 視圖
現在我們隻需要通過點選給定的登入按鈕來打開顫振視圖。
讓我們使用 Login 按鈕的 @IBAction 并添加代碼以在其塊中打開 Flutter 視圖,是以我們的 ViewController 将如下所示,
import UIKit
import Flutter
class ViewController: UIViewController {
@IBOutlet weak var loginButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
loginButton.layer.cornerRadius = loginButton.frame.height / 2
}
@IBAction func onLoginBtnClick(_ sender: UIButton) {
let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
present(flutterViewController, animated: true, completion: nil)
}
}
很容易了解,不是嗎?
它隻是從 AppDelegate 類中擷取 Flutter 引擎的對象,并使用它通過 FlutterViewController 打開視圖。
而已。 現在您可以運作應用程式了!
關注七爪網,擷取更多APP/小程式/網站源碼資源!