Skip to content

Commit

Permalink
Make embedded wrapper a UIView
Browse files Browse the repository at this point in the history
  • Loading branch information
crow committed Aug 18, 2024
1 parent a5f2227 commit f4229fe
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 33 deletions.
88 changes: 65 additions & 23 deletions ios/Classes/AirshipEmbeddedView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,61 @@ class AirshipEmbeddedViewFactory: NSObject, FlutterPlatformViewFactory {
}
}

class AirshipEmbeddedViewWrapper: NSObject, FlutterPlatformView {
class AirshipEmbeddedViewWrapper: UIView, FlutterPlatformView {
private static let embeddedIdKey: String = "embeddedId"

@ObservedObject
var viewModel = FlutterAirshipEmbeddedView.ViewModel()

public var viewController: UIViewController?
public var viewController: UIViewController

public var isAdded: Bool = false

let channel: FlutterMethodChannel
private var _view: UIView

init(frame: CGRect, viewId: Int64, registrar: FlutterPluginRegistrar, args: Any?) {
required init(frame: CGRect, viewId: Int64, registrar: FlutterPluginRegistrar, args: Any?) {
let channelName = "com.airship.flutter/EmbeddedView_\(viewId)"
self.channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger())
_view = UIView(frame: frame)

super.init()
self.viewController = UIHostingController(
rootView: FlutterAirshipEmbeddedView(viewModel: self.viewModel)
)

let rootView = FlutterAirshipEmbeddedView(viewModel: viewModel)
self.viewController.view.backgroundColor = UIColor.purple

let rootView = FlutterAirshipEmbeddedView(viewModel: self.viewModel)
self.viewController = UIHostingController(
rootView: rootView
)

_view.translatesAutoresizingMaskIntoConstraints = false
_view.addSubview(self.viewController!.view)
self.viewController?.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
super.init(frame:frame)

Task { @MainActor in
if let params = args as? [String: Any], let embeddedId = params[Self.embeddedIdKey] as? String {
rootView.viewModel.embeddedID = embeddedId
}
self.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(self.viewController.view)
self.viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

rootView.viewModel.size = frame.size
if let params = args as? [String: Any], let embeddedId = params[Self.embeddedIdKey] as? String {
rootView.viewModel.embeddedID = embeddedId
}

rootView.viewModel.size = frame.size

channel.setMethodCallHandler { [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) in
self?.handle(call, result: result)
}
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getSize":
let width = _view.bounds.width
let height = _view.bounds.height
let width = self.bounds.width
let height = self.bounds.height
result(["width": width, "height": height])
case "getIsAdded":
result(["isAdded": self.isAdded])
default:
result(FlutterError(code: "UNAVAILABLE",
message: "Unknown method: \(call.method)",
Expand All @@ -72,20 +81,39 @@ class AirshipEmbeddedViewWrapper: NSObject, FlutterPlatformView {
}

func view() -> UIView {
return _view
return self
}

public override func didMoveToWindow() {
super.didMoveToWindow()
guard !self.isAdded else { return }
self.viewController.willMove(toParent: self.parentViewController())
self.parentViewController().addChild(self.viewController)
self.viewController.didMove(toParent: self.parentViewController())
self.viewController.view.isUserInteractionEnabled = true
isAdded = true
}

override func layoutSubviews() {
super.layoutSubviews()
self.viewModel.size = bounds.size
}
}

struct FlutterAirshipEmbeddedView: View {
@ObservedObject
var viewModel: ViewModel

init(viewModel: ViewModel) {
self.viewModel = viewModel
}

var body: some View {
if let embeddedID = viewModel.embeddedID {
AirshipEmbeddedView(embeddedID: embeddedID,
embeddedSize: .init(
parentWidth: viewModel.width,
parentHeight: viewModel.height
parentWidth: viewModel.size?.width,
parentHeight: viewModel.size?.height
)
) {
Text("Placeholder: \(embeddedID) \(viewModel.size ?? CGSize())")
Expand All @@ -102,16 +130,30 @@ struct FlutterAirshipEmbeddedView: View {

var height: CGFloat {
guard let height = self.size?.height, height > 0 else {
return (try? AirshipUtils.mainWindow()?.screen.bounds.height) ?? 420
return try! AirshipUtils.mainWindow()?.screen.bounds.height ?? 500
}
return height
}

var width: CGFloat {
guard let width = self.size?.width, width > 0 else {
return (try? AirshipUtils.mainWindow()?.screen.bounds.width) ?? 420
return try! AirshipUtils.mainWindow()?.screen.bounds.width ?? 500
}
return width
}
}
}

extension UIView {
//Get Parent View Controller from any view
func parentViewController() -> UIViewController {
var responder: UIResponder? = self
while !(responder is UIViewController) {
responder = responder?.next
if nil == responder {
break
}
}
return (responder as? UIViewController)!
}
}
19 changes: 9 additions & 10 deletions lib/src/airship_embedded_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ class EmbeddedViewState extends State<EmbeddedView> {
_getNativeViewSize();
}


/// Fall back to screen-sized constraints when constraints can be inferred
Widget wrapWithLayoutBuilder(Widget view) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
double width = constraints.maxWidth;
double height = constraints.maxHeight;
double width = _nativeViewWidth;
double height = _nativeViewHeight;

if (width == 0 || width == double.infinity) {
width = MediaQuery.of(context).size.width;
Expand All @@ -71,17 +72,15 @@ class EmbeddedViewState extends State<EmbeddedView> {
height = MediaQuery.of(context).size.height;
}

return FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: ConstrainedBox(
return ConstrainedBox(
constraints: BoxConstraints(
maxWidth: width,
maxHeight: height,
minWidth: 10,
minHeight: 10,
maxWidth: MediaQuery.of(context).size.width,
maxHeight: MediaQuery.of(context).size.height
),
child: view,
),
);
);
},
);
}
Expand Down

0 comments on commit f4229fe

Please sign in to comment.