I’ve three uiViewController with seperate nativePlatformViewFactor for every. However just one is being offered on the window view hierarchy despite the fact that I’ve correctly initialised every certainly one of them because of this I’ve to resort utilizing single uiViewController for these completely different options based mostly on flags.
AppDelegate.swift
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func software(
_ software: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
if #accessible(iOS 10.0, *) {
UNUserNotificationCenter.present().delegate = self as? UNUserNotificationCenterDelegate
}
// That is required to make any communication accessible within the motion isolate.
FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
GeneratedPluginRegistrant.register(with: registry)
}
GeneratedPluginRegistrant.register(with: self)
//runner or flutter
if #accessible(iOS 14.0, *) {
let plugin : FlutterPluginRegistrar = registrar(forPlugin: "flutter")!
let nativeMlView = FLNativeViewFactory(messenger: plugin.messenger())
let reportViewFactory = ReportNativeViewFactory(messenger: plugin.messenger())
let inhalerDetectionViewFactory = InhalerDetectionViewFactory(messenger: plugin.messenger())
plugin.register(nativeMlView, withId: "native_ml_view")
plugin.register(reportViewFactory, withId: "edit_report_native_ml_view")
plugin.register(inhalerDetectionViewFactory, withId: "verify_inhaler_view")
} else {
// Fallback on earlier variations
}
return tremendous.software(software, didFinishLaunchingWithOptions: launchOptions)
}
}
Within the beneath viewFactory I’m compelled to make use of MainViewController inspite of OcrViewController as a result of it will not connect its view to superview.
InhalerDetectionViewFactory.swift
@accessible(iOS 14.0, *)
class InhalerDetectionViewFactory: NSObject, FlutterPlatformViewFactory {
personal var messenger: FlutterBinaryMessenger
init(messenger: FlutterBinaryMessenger) {
self.messenger = messenger
tremendous.init()
}
func create(
withFrame body: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?
) -> FlutterPlatformView {
return InhalerDetectionNativeView(
body: body,
viewIdentifier: viewId,
arguments: args
)
}
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}
class InhalerDetectionNativeView: NSObject, FlutterPlatformView {
let width: String
let top: String
personal var _view: UIView
let medicineList : [String]
init(
body: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?
) {
_view = UIView()
_view.backgroundColor = UIColor.black
if let arguments = args as? [String: Any],
let wdth = arguments["width"] as? String,
let ht = arguments["height"] as? String,
let meds = arguments["medicineList"] as? [String] {
width = wdth;
top = ht;
medicineList = meds;
} else {
width = "0"
top = "0"
medicineList = ["test1", "test2", "test3", "test4", "test5","test6","test7","test8"]
}
let controller : FlutterViewController = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.keyWindow?.rootViewController as! FlutterViewController
let mainStoryboard: UIStoryboard = UIStoryboard(identify: "Fundamental", bundle: Bundle.predominant)
// let vc = mainStoryboard.instantiateViewController(identifier: "OcrVC")
// if let ocrVC : OcrViewController = vc as? OcrViewController {
// ocrVC.channel = FlutterMethodChannel(identify: "inhaler_verification", binaryMessenger: controller.binaryMessenger)
//
// print("OcrViewController initialised")
// print(String.init(describing: "Vc hash: (vc.hash), isLoaded: (vc.isViewLoaded)"))
// }
let vc = mainStoryboard.instantiateViewController(identifier: "MainVC")
if let mainVC : MainViewController = vc as? MainViewController {
mainVC.channel = FlutterMethodChannel(identify: "inhaler_verification", binaryMessenger: controller.binaryMessenger)
mainVC.stepId = ""
mainVC.withSpacer = false
mainVC.isEditReport = false
mainVC.medicineList = medicineList
print("MainViewController initialised")
print(String.init(describing: "Vc hash: (vc.hash), isLoaded: (vc.isViewLoaded)"))
}
_view.body = CGRect(x: 0, y: 0, width: Int(width) ?? 0, top: Int(top) ?? 0)
_view.addSubview(vc.view)
tremendous.init()
}
func view() -> UIView {
return _view
}
}
Similar for the remainder of platformViewFactories I’m compelled to make use of MainViewController because the rendering UiView.
MainViewController.swift
import UIKit
import Imaginative and prescient
import Flutter
import AVFoundation
import VisionKit
@accessible(iOS 14.0, *)
class MainViewController: UIViewController {
var previewLayer: AVCaptureVideoPreviewLayer?
@IBOutlet var imageView: UIImageView!
@IBOutlet weak var labelStack: UIStackView!
@IBOutlet weak var actionLabel: UILabel!
@IBOutlet weak var cameraButton: UIButton!
var stepNumber:Int = 1
var videoCapture: VideoCapture!
var videoProcessingChain: VideoProcessingChain!
var actionFrameCounts = [String: Int]()
@IBOutlet weak var shakeStack: UIStackView!
@IBOutlet weak var shakeCountLabel: UILabel!
@IBOutlet weak var timerView: UIView!
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var medVerifyErrorView: UIView!
var channel: FlutterMethodChannel
let channelName = "take_test"
var stepId: String
var stepIndex: Int = 0
var withSpacer: Bool
var isEditReport: Bool
var medicineList : [String] = []
var medicineVerified = false
@IBOutlet weak var instructionLableView: UIView!
personal let dataScannerViewController = DataScannerViewController(recognizedDataTypes: [.text()],
qualityLevel: .balanced,
recognizesMultipleItems: false,
isHighFrameRateTrackingEnabled: true,
isPinchToZoomEnabled: true,
isGuidanceEnabled: true,
isHighlightingEnabled: true)
personal var scannerAvailable: Bool { DataScannerViewController.isSupported && DataScannerViewController.isAvailable }
init(stepId: String, viewId: Int64, isEditReport: Bool) {
let controller : FlutterViewController = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.keyWindow?.rootViewController as! FlutterViewController
channel = FlutterMethodChannel(identify: isEditReport ? "report_ocr_scan" : "take_test", binaryMessenger: controller.binaryMessenger)
self.stepId = stepId
self.withSpacer = false
self.isEditReport = isEditReport
self.medicineList = []
tremendous.init(nibName: "MainViewController", bundle: Bundle.predominant)
}
required init?(coder: NSCoder) {
channel = FlutterMethodChannel()
stepId = ""
withSpacer = false;
isEditReport = false;
medicineList = [];
tremendous.init(coder: coder)
}
override func viewDidLoad() {
tremendous.viewDidLoad()
// Disable the idle timer to stop the display from locking.
UIApplication.shared.isIdleTimerDisabled = true
hideInstructionView()
medVerifyErrorView.isHidden = true
if (isEditReport) {
labelStack.isHidden = true
shakeStack.isHidden = true
dataScannerViewController.delegate = self
if scannerAvailable {
current(dataScannerViewController, animated: true)
view.layer.addSublayer(dataScannerViewController.view.layer)
dataScannerViewController.view.body = view.body
strive? dataScannerViewController.startScanning()
}
} else {
if (medicineList.isEmpty) {
setupImage()
} else {
dataScannerViewController.delegate = self
if scannerAvailable {
current(dataScannerViewController, animated: true)
view.layer.addSublayer(dataScannerViewController.view.layer)
dataScannerViewController.view.body = view.body
strive? dataScannerViewController.startScanning()
}
}
}
channel.setMethodCallHandler(deal with)
}
override func viewDidAppear(_ animated: Bool) {
tremendous.viewDidAppear(animated)
// Replace the system's orientation.
//videoCapture.updateDeviceOrientation()
}
personal func deal with(_ name: FlutterMethodCall, consequence: @escaping FlutterResult) {
swap name.methodology {
case "next_step":
let arguments = name.arguments as! [Dictionary<String, Any?>]
let stepId = arguments.first?["stepId"] as! String
self.stepId = stepId
consequence("subsequent step initialized")
case "dealloc_resources":
print("Technique name from flutter to dealloc sources")
self.videoCapture = nil
self.videoCapture?.delegate = nil
self.videoProcessingChain = nil
self.videoProcessingChain?.delegate = nil
self.dismiss(animated: false)
consequence("receiveFromFlutter success")
default:
consequence(FlutterMethodNotImplemented)
}
}
override func viewWillDisappear(_ animated: Bool) {
print("View will disappear")
if (!isEditReport) {
videoCapture = nil
videoCapture?.delegate = nil
videoProcessingChain = nil
videoProcessingChain?.delegate = nil
}
tremendous.viewWillDisappear(animated)
}
func setupImage() {
let captureSession = AVCaptureSession()
guard let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, place: .entrance) else{ return }
guard let enter = strive? AVCaptureDeviceInput(system: captureDevice) else { return }
captureSession.addInput(enter)
let dataOutput = AVCaptureVideoDataOutput()
dataOutput.setSampleBufferDelegate(self, queue:DispatchQueue(label: "videoQueue"))
captureSession.addOutput(dataOutput)
DispatchQueue.international(qos: .background).async {
captureSession.startRunning()
}
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.body = view.body
self.imageView.layer.addSublayer(previewLayer)
previewLayer.videoGravity = .resizeAspectFill
self.previewLayer = previewLayer
self.shakeStack.isHidden = true
}
func stopCaptureSession() {
guard let captureSession = previewLayer?.session else { return }
DispatchQueue.predominant.async {
self.previewLayer?.removeFromSuperlayer()
self.previewLayer = nil
}
DispatchQueue.international(qos: .background).async {
if captureSession.isRunning {
captureSession.stopRunning()
}
}
}
}
I attempted numerous options for a number of platformViews however not in a position to determine so I’m at present utilizing single UIViewController for all of the platformViewFactories.