перечисление встроенного переключателя экрана
Код: Выделить всё
import Foundation
import Flutter
enum ViewControllerGetter: String {
case viewController
case viewController2
func getViewController (with params: [String: AnyObject]?) -> UIViewController? {
switch self {
case .viewController:
if params != nil {
var vc : UIViewController = UIViewController()
// first we get the binaryMessenger from params as it has been added to them in FlutterPlatformView
if let binaryMessenger = params!["binaryMessenger"] as? FlutterBinaryMessenger {
print("ViewControllerGetter binaryMessenger \(binaryMessenger.description)");
// then we initialize the ViewController with it, to create a FLutterMethodChannel which needs a binaryMessenger
// than normally we take from AppDelegate rootViewController, but as theis is a Plug-in we don't have any AppDelegate
let vcToShow = ViewController(withParameter: binaryMessenger, methodChannelId: params!["methodChannelId"] as! String);
// then we set other ViwController variables and values
if let param1 = params!["param 1"] {
vcToShow.buttonTitleA = param1 as? String
}
if let param2 = params!["param 2"] {
vcToShow.buttonTitleB = param2 as? String
}
// then we overwrite the Empty ViewController to be returned with the instantiated ViewController
vc = vcToShow
}
// we can finally return the ViewController to be attached to the FlutterPlatformView UIView
return vc
}
case .viewController2:
if params != nil {
var vc : UIViewController = UIViewController()
// first we get the binaryMessenger from params as it has been added to them in FlutterPlatformView
if let binaryMessenger = params!["binaryMessenger"] as? FlutterBinaryMessenger {
print("ViewControllerGetter binaryMessenger \(binaryMessenger.description)");
// then we initialize the ViewController with it, to create a FlutterMethodChannel which needs a binaryMessenger
// than normally we take from AppDelegate rootViewController, but as this is a Plug-in we don't have any AppDelegate
let vcToShow = ViewController2(withParameter: binaryMessenger, methodChannelId: params!["methodChannelId"] as! String);
// then we set other ViewController variables and values
if let param1 = params!["param 1"] {
vcToShow.buttonTitleA = param1 as? String
}
if let param2 = params!["param 2"] {
vcToShow.buttonTitleB = param2 as? String
}
if let param3 = params!["param 3"] {
vcToShow.buttonTitleC = param3 as? String
}
// then we overwrite the Empty ViewController to be returned with the instantiated ViewController
vc = vcToShow
}
// we can finally return the ViewController to be attached to the FlutterPlatformView UIVIew
return vc
}
}
return nil
}
}
Код: Выделить всё
import Flutter
import UIKit
class DynamicNativeViewFactory: NSObject, FlutterPlatformViewFactory {
private var messenger: FlutterBinaryMessenger
init(messenger: FlutterBinaryMessenger) {
self.messenger = messenger
super.init()
}
func create(
withFrame frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?
) -> FlutterPlatformView {
return DynamicNativeView(
frame: frame,
viewIdentifier: viewId,
arguments: args,
binaryMessenger: messenger)
}
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}
class DynamicNativeView: NSObject, FlutterPlatformView {
private var vc: UIViewController = UIViewController();
init(
frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?,
binaryMessenger messenger: FlutterBinaryMessenger?
) {
if var params = args as? [String:AnyObject] {
print("DynamicNativeView binaryMessenger \(messenger?.description)");
let screen: String = params["screen"] as! String;
// we add the binary messenger
params["binaryMessenger"] = messenger;
if let vcToShow = ViewControllerGetter(rawValue: screen)?.getViewController(with: params) {
vc = vcToShow
// _view = vcToShow.view /// breaks touch
}
}
super.init()
// _view.addSubview(vc.view)
}
func view() -> UIView {
// _view.addSubview(vc.view)
// return _view
return vc.view
}
}
Код: Выделить всё
import Flutter
import UIKit
public class NativePlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "native_plugin", binaryMessenger: registrar.messenger())
let instance = NativePlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
let viewFactory = DynamicNativeViewFactory(messenger: registrar.messenger())
registrar.register(
viewFactory,
withId: "native_screen"
)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getPlatformVersion":
result("iOS " + UIDevice.current.systemVersion)
default:
result(FlutterMethodNotImplemented)
}
}
}
Код: Выделить всё
class NativeViewer extends StatefulWidget {
final Map viewParams;
const NativeViewer({
super.key,
required this.viewParams,
});
@override
State createState() => _NativeViewerState();
}
class _NativeViewerState extends State {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
const String viewType = 'native_screen';
final Map creationParams = widget.viewParams;
return AdatptivePlatformView(
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
);
}
}
class AdatptivePlatformView extends StatelessWidget {
final String viewType;
final dynamic creationParams;
final TextDirection? layoutDirection;
final MessageCodec? creationParamsCodec;
const AdatptivePlatformView({
super.key,
required this.viewType,
this.creationParams,
this.creationParamsCodec,
this.layoutDirection,
});
@override
Widget build(BuildContext context) {
return Platform.isAndroid
? AndroidView(
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
)
: UiKitView(
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
gestureRecognizers: {
Factory(
() => EagerGestureRecognizer(),
),
},
);
}
}
Меня беспокоит следующее: что при регистрации только одного FlutterPlatformViewFactory с помощью плагина будет гарантировано отсутствие проблем с идентификатором, поскольку он только один, это может привести к таким проблемам, как утечки памяти, например, когда я использую виджет плагина на разных экранах Flutter, поэтому плагин зарегистрировал бы его снова с тем же идентификатором.
Я не нашел в документации никаких упоминаний о его отмене регистрации, поэтому я не знаю, является ли это безопасным подходом, поскольку, возможно, FlutterPlatformViewFactory получает отменяется регистрация при закрытии экрана Flutter, который использует виджет плагина, освобождая ресурсы, захваченные, как это происходит, когда новый FlutterMethodChannelHandler регистрируется на том же канале, отменяя регистрацию любого ранее зарегистрированного или он все равно остается зарегистрированным.Можете ли вы указать мне на какую-то часть документации, которую я пропустил, или на какую-либо статью или какой-нибудь плагин Flutter, который имеет несколько собственных экранов для своего пользовательского интерфейса?
Как всегда, ваша помощь очень ценится
Подробнее здесь: https://stackoverflow.com/questions/789 ... ve-screens