From 3f54730e188b0f13a7e7f150900d9868eeb8c37d Mon Sep 17 00:00:00 2001 From: farfromrefuge Date: Thu, 16 Nov 2023 16:26:24 +0100 Subject: [PATCH 1/4] fix: modal dialog root view now has the `rootView` as parent to be able to access the `ns-root` class which comply with css specs (for example to read root css variables) --- packages/core/ui/core/view/index.android.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/ui/core/view/index.android.ts b/packages/core/ui/core/view/index.android.ts index 39a7161278..f353703018 100644 --- a/packages/core/ui/core/view/index.android.ts +++ b/packages/core/ui/core/view/index.android.ts @@ -232,6 +232,7 @@ function initializeDialogFragment() { const owner = this.owner; this.activity = new WeakRef(this.getActivity()); owner._setupAsRootView(this.getActivity()); + owner.parent = Application.getRootView(); owner._isAddedToNativeVisualTree = true; // we need to set the window SoftInputMode here. From cb7743c85362775e5b2e35616d86667b4350555a Mon Sep 17 00:00:00 2001 From: farfromrefuge Date: Thu, 16 Nov 2023 16:33:39 +0100 Subject: [PATCH 2/4] fix(ios): modal parent for ios --- packages/core/ui/core/view/index.ios.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/core/ui/core/view/index.ios.ts b/packages/core/ui/core/view/index.ios.ts index 0df1791ec9..40fc93bcf1 100644 --- a/packages/core/ui/core/view/index.ios.ts +++ b/packages/core/ui/core/view/index.ios.ts @@ -18,6 +18,7 @@ import type { ModalTransition } from '../../transition/modal-transition'; import { SharedTransition } from '../../transition/shared-transition'; import { GestureStateTypes, PanGestureEventData } from '../../gestures'; import { NativeScriptUIView } from '../../utils'; +import { Application } from '../../../application'; export * from './view-common'; // helpers (these are okay re-exported here) @@ -503,6 +504,7 @@ export class View extends ViewCommon implements ViewDefinition { if (!controller) { const nativeView = this.ios || this.nativeViewProtected; controller = IOSHelper.UILayoutViewController.initWithOwner(new WeakRef(this)); + this.parent = Application.getRootView(); if (nativeView instanceof UIView) { controller.view.addSubview(nativeView); From cb5230169735b237f001fb5320ffca860b1e4407 Mon Sep 17 00:00:00 2001 From: farfromrefuge Date: Thu, 16 Nov 2023 16:53:48 +0100 Subject: [PATCH 3/4] fix: cleanup the modal parent once closed. on iOS as the UILayoutViewController can be used for other widget we need to let it know it is for modal so that it still loads/unloads the view (there was a test for parent). --- packages/core/ui/core/view/index.android.ts | 1 + packages/core/ui/core/view/index.ios.ts | 5 +++-- packages/core/ui/core/view/view-common.ts | 1 + packages/core/ui/core/view/view-helper/index.d.ts | 3 ++- packages/core/ui/core/view/view-helper/index.ios.ts | 7 +++++-- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/core/ui/core/view/index.android.ts b/packages/core/ui/core/view/index.android.ts index f353703018..85e0b5f71c 100644 --- a/packages/core/ui/core/view/index.android.ts +++ b/packages/core/ui/core/view/index.android.ts @@ -298,6 +298,7 @@ function initializeDialogFragment() { owner._isAddedToNativeVisualTree = false; owner._tearDownUI(true); + owner.parent = null; } } } diff --git a/packages/core/ui/core/view/index.ios.ts b/packages/core/ui/core/view/index.ios.ts index 40fc93bcf1..481ca8d80e 100644 --- a/packages/core/ui/core/view/index.ios.ts +++ b/packages/core/ui/core/view/index.ios.ts @@ -500,10 +500,11 @@ export class View extends ViewCommon implements ViewDefinition { this._setupAsRootView({}); super._showNativeModalView(parentWithController, options); - let controller = this.viewController; + let controller: IOSHelper.UILayoutViewController = this.viewController; if (!controller) { const nativeView = this.ios || this.nativeViewProtected; - controller = IOSHelper.UILayoutViewController.initWithOwner(new WeakRef(this)); + controller = IOSHelper.UILayoutViewController.initWithOwner(new WeakRef(this)); + controller.modal = true; this.parent = Application.getRootView(); if (nativeView instanceof UIView) { diff --git a/packages/core/ui/core/view/view-common.ts b/packages/core/ui/core/view/view-common.ts index ad3e3cf26e..9fe4250f35 100644 --- a/packages/core/ui/core/view/view-common.ts +++ b/packages/core/ui/core/view/view-common.ts @@ -436,6 +436,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition { } this._tearDownUI(true); + this.parent = null; } }; diff --git a/packages/core/ui/core/view/view-helper/index.d.ts b/packages/core/ui/core/view/view-helper/index.d.ts index 0635b7415e..5d0890faa5 100644 --- a/packages/core/ui/core/view/view-helper/index.d.ts +++ b/packages/core/ui/core/view/view-helper/index.d.ts @@ -54,8 +54,9 @@ export namespace IOSHelper { export function getFrameFromPosition(position: { left; top; right; bottom }, insets?: { left; top; right; bottom }): any; /* CGRect */ export function shrinkToSafeArea(view: View, frame: any /* CGRect */): any; /* CGRect */ export function expandBeyondSafeArea(view: View, frame: any /* CGRect */): any; /* CGRect */ - export class UILayoutViewController { + export class UILayoutViewController extends UIViewController { public static initWithOwner(owner: WeakRef): UILayoutViewController; + modal?: boolean; } export class UIAdaptivePresentationControllerDelegateImp { public static initWithOwnerAndCallback(owner: WeakRef, whenClosedCallback: Function): UIAdaptivePresentationControllerDelegateImp; diff --git a/packages/core/ui/core/view/view-helper/index.ios.ts b/packages/core/ui/core/view/view-helper/index.ios.ts index 53d8f214bf..6ab9b02479 100644 --- a/packages/core/ui/core/view/view-helper/index.ios.ts +++ b/packages/core/ui/core/view/view-helper/index.ios.ts @@ -11,6 +11,9 @@ export * from './view-helper-common'; @NativeClass class UILayoutViewController extends UIViewController { public owner: WeakRef; + // used to know if we are a modal controller + // in this case the owner has a parent (rootView) but we still need to load/unload it + public modal; public static initWithOwner(owner: WeakRef): UILayoutViewController { const controller = UILayoutViewController.new(); @@ -97,7 +100,7 @@ class UILayoutViewController extends UIViewController { IOSHelper.updateAutoAdjustScrollInsets(this, owner); - if (!owner.isLoaded && !owner.parent) { + if (!owner.isLoaded && (!owner.parent || this.modal)) { owner.callLoaded(); } } @@ -105,7 +108,7 @@ class UILayoutViewController extends UIViewController { public viewDidDisappear(animated: boolean): void { super.viewDidDisappear(animated); const owner = this.owner?.deref(); - if (owner && owner.isLoaded && !owner.parent) { + if (owner && owner.isLoaded && (!owner.parent || this.modal)) { owner.callUnloaded(); } } From 5f4d0e9b6f2884f86cb0edcea90d0986a41b32f6 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Fri, 24 Nov 2023 11:22:08 +0100 Subject: [PATCH 4/4] fix: always set the parent --- packages/core/ui/core/view/index.ios.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/ui/core/view/index.ios.ts b/packages/core/ui/core/view/index.ios.ts index 481ca8d80e..2bb19415c0 100644 --- a/packages/core/ui/core/view/index.ios.ts +++ b/packages/core/ui/core/view/index.ios.ts @@ -505,7 +505,6 @@ export class View extends ViewCommon implements ViewDefinition { const nativeView = this.ios || this.nativeViewProtected; controller = IOSHelper.UILayoutViewController.initWithOwner(new WeakRef(this)); controller.modal = true; - this.parent = Application.getRootView(); if (nativeView instanceof UIView) { controller.view.addSubview(nativeView); @@ -513,6 +512,8 @@ export class View extends ViewCommon implements ViewDefinition { this.viewController = controller; } + // we set the parent to root to access all css root variables + this.parent = Application.getRootView(); if (options.transition) { controller.modalPresentationStyle = UIModalPresentationStyle.Custom;