Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions apps/automated/src/ui/tab-view/tab-view-root-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,11 @@ export function test_offset_zero_should_raise_same_events() {
resetActualEventsRaised();
waitUntilNavigatedToMaxTimeout([items[2].page], () => (tabView.selectedIndex = 2));

const startEvents = ['Tab0 Frame0 Page0 unloaded', 'Tab0 Frame0 unloaded'];
if (__APPLE__) {
startEvents.push('Tab0 Frame0 Page0 navigatingFrom');
}
const expectedEventsRaisedAfterSelectThirdTab = [startEvents, [], ['Tab2 Frame2 loaded', 'Tab2 Frame2 Page2 navigatingTo', 'Tab2 Frame2 Page2 loaded', 'Tab2 Frame2 Page2 navigatedTo']];
const expectedEventsRaisedAfterSelectThirdTab = [['Tab0 Frame0 Page0 unloaded', 'Tab0 Frame0 unloaded'], [], ['Tab2 Frame2 loaded', 'Tab2 Frame2 Page2 navigatingTo', 'Tab2 Frame2 Page2 loaded', 'Tab2 Frame2 Page2 navigatedTo']];

TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterSelectThirdTab);

resetActualEventsRaised();

waitUntilTabViewReady(items[0].page, () => (tabView.selectedIndex = 0));

const expectedEventsRaisedAfterReturnToFirstTab = [['Tab0 Frame0 Page0 loaded', 'Tab0 Frame0 loaded'], [], ['Tab2 Frame2 Page2 unloaded', 'Tab2 Frame2 unloaded']];
Expand Down
6 changes: 5 additions & 1 deletion packages/core/ui/frame/frame-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Page } from '../page';
import { View, CustomLayoutView, CSSType } from '../core/view';
import { Property } from '../core/properties';
import { Trace } from '../../trace';
import { frameStack, topmost as frameStackTopmost, _pushInFrameStack, _popFromFrameStack, _removeFromFrameStack } from './frame-stack';
import { frameStack, topmost as frameStackTopmost, _pushInFrameStack, _popFromFrameStack, _removeFromFrameStack, _isFrameStackEmpty } from './frame-stack';
import { viewMatchesModuleContext } from '../core/view/view-common';
import { getAncestor } from '../core/view-base';
import { Builder } from '../builder';
Expand Down Expand Up @@ -542,6 +542,10 @@ export class FrameBase extends CustomLayoutView {
}
}

public _isFrameStackEmpty() {
return _isFrameStackEmpty();
}

public _pushInFrameStack() {
_pushInFrameStack(this);
}
Expand Down
6 changes: 4 additions & 2 deletions packages/core/ui/frame/frame-interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ export interface NavigationEntry extends ViewEntry {
}

export interface NavigationContext {
entry: BackstackEntry;
// TODO: remove isBackNavigation for NativeScript 7.0
entry?: BackstackEntry;
/**
* @deprecated Use navigationType instead.
*/
isBackNavigation: boolean;
navigationType: NavigationType;
}
Expand Down
4 changes: 4 additions & 0 deletions packages/core/ui/frame/frame-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export function topmost(): FrameBase {
return undefined;
}

export function _isFrameStackEmpty(): boolean {
return frameStack.length === 0;
}

export function _pushInFrameStack(frame: FrameBase): void {
if (frame._isInFrameStack && frameStack[frameStack.length - 1] === frame) {
return;
Expand Down
9 changes: 8 additions & 1 deletion packages/core/ui/frame/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ export class Frame extends FrameBase {
* @private
*/
_updateBackstack(entry: BackstackEntry, navigationType: NavigationType): void;
/**
* @private
*/
_isFrameStackEmpty(): boolean;
/**
* @private
*/
Expand Down Expand Up @@ -404,7 +408,10 @@ export interface NavigationEntry extends ViewEntry {
* Represents a context passed to navigation methods.
*/
export interface NavigationContext {
entry: BackstackEntry;
entry?: BackstackEntry;
/**
* @deprecated Use navigationType instead.
*/
isBackNavigation: boolean;
navigationType: NavigationType;
}
Expand Down
66 changes: 28 additions & 38 deletions packages/core/ui/frame/index.ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { IOSHelper } from '../core/view/view-helper';
import { profile } from '../../profiling';
import { CORE_ANIMATION_DEFAULTS, ios as iOSUtils, layout } from '../../utils';
import { Trace } from '../../trace';
import type { PageTransition } from '../transition/page-transition';
import { SlideTransition } from '../transition/slide-transition';
import { FadeTransition } from '../transition/fade-transition';
import { SharedTransition } from '../transition/shared-transition';
Expand All @@ -22,11 +21,11 @@ const NAV_DEPTH = '_navDepth';
const TRANSITION = '_transition';
const NON_ANIMATED_TRANSITION = 'non-animated';

let navDepth = -1;
let navDepth: number = -1;
let navControllerDelegate: UINavigationControllerDelegate = null;

export class Frame extends FrameBase {
viewController: UINavigationControllerImpl;
_animatedDelegate: UINavigationControllerDelegate;
public _ios: iOSFrame;
iosNavigationBarClass: typeof NSObject;
iosToolbarClass: typeof NSObject;
Expand All @@ -38,6 +37,11 @@ export class Frame extends FrameBase {
}

createNativeView() {
// Push frame back in frame stack since it was removed in disposeNativeView() method.
if (this._currentEntry) {
this._pushInFrameStack();
}

return this.viewController.view;
}

Expand All @@ -61,7 +65,12 @@ export class Frame extends FrameBase {

this._removeFromFrameStack();
this.viewController = null;
this._animatedDelegate = null;

// This was the last frame so we can get rid of the controller delegate reference
if (this._isFrameStackEmpty()) {
navControllerDelegate = null;
}

if (this._ios) {
this._ios.controller = null;
this._ios = null;
Expand Down Expand Up @@ -120,11 +129,12 @@ export class Frame extends FrameBase {

const nativeTransition = _getNativeTransition(navigationTransition, true);
if (!nativeTransition && navigationTransition) {
if (!this._animatedDelegate) {
this._animatedDelegate = <UINavigationControllerDelegate>UINavigationControllerAnimatedDelegate.initWithOwner(new WeakRef(this));
if (!navControllerDelegate) {
navControllerDelegate = <UINavigationControllerDelegate>UINavigationControllerAnimatedDelegate.new();
}
this._ios.controller.delegate = this._animatedDelegate;
viewController[DELEGATE] = this._animatedDelegate;

this._ios.controller.delegate = navControllerDelegate;
viewController[DELEGATE] = navControllerDelegate;
if (navigationTransition.instance) {
this.transitionId = navigationTransition.instance.id;
const transitionState = SharedTransition.getState(this.transitionId);
Expand Down Expand Up @@ -346,19 +356,6 @@ export class Frame extends FrameBase {
public _setNativeViewFrame(nativeView: UIView, frame: CGRect) {
//
}

public _onNavigatingTo(backstackEntry: BackstackEntry, isBack: boolean) {
// for now to not break iOS events chain (calling navigation events from controller delegates)
// we dont call super(which would also trigger events) but only notify the frame of the navigation
// though it means events are not triggered at the same time (lifecycle) on iOS / Android
this.notify({
eventName: Page.navigatingToEvent,
object: this,
isBack,
entry: backstackEntry,
fromEntry: this._currentEntry,
});
}
}

const transitionDelegates = new Array<TransitionDelegate>();
Expand Down Expand Up @@ -413,14 +410,6 @@ class TransitionDelegate extends NSObject {
@NativeClass
class UINavigationControllerAnimatedDelegate extends NSObject implements UINavigationControllerDelegate {
public static ObjCProtocols = [UINavigationControllerDelegate];
owner: WeakRef<Frame>;
transition: PageTransition;

static initWithOwner(owner: WeakRef<Frame>) {
const delegate = <UINavigationControllerAnimatedDelegate>UINavigationControllerAnimatedDelegate.new();
delegate.owner = owner;
return delegate;
}

navigationControllerAnimationControllerForOperationFromViewControllerToViewController(navigationController: UINavigationController, operation: number, fromVC: UIViewController, toVC: UIViewController): UIViewControllerAnimatedTransitioning {
let viewController: UIViewController;
Expand All @@ -445,29 +434,30 @@ class UINavigationControllerAnimatedDelegate extends NSObject implements UINavig
if (Trace.isEnabled()) {
Trace.write(`UINavigationControllerImpl.navigationControllerAnimationControllerForOperationFromViewControllerToViewController(${operation}, ${fromVC}, ${toVC}), transition: ${JSON.stringify(navigationTransition)}`, Trace.categories.NativeLifecycle);
}
this.transition = navigationTransition.instance;

if (!this.transition) {
let transition = navigationTransition.instance;

if (!transition) {
if (navigationTransition.name) {
const curve = _getNativeCurve(navigationTransition);
const name = navigationTransition.name.toLowerCase();
if (name.indexOf('slide') === 0) {
const direction = name.substring('slide'.length) || 'left'; //Extract the direction from the string
this.transition = new SlideTransition(direction, navigationTransition.duration, curve);
const direction = name.substring('slide'.length) || 'left'; // Extract the direction from the string
transition = new SlideTransition(direction, navigationTransition.duration, curve);
} else if (name === 'fade') {
this.transition = new FadeTransition(navigationTransition.duration, curve);
transition = new FadeTransition(navigationTransition.duration, curve);
}
}
}

if (this.transition?.iosNavigatedController) {
return this.transition.iosNavigatedController(navigationController, operation, fromVC, toVC);
if (transition?.iosNavigatedController) {
return transition.iosNavigatedController(navigationController, operation, fromVC, toVC);
}
return null;
}

navigationControllerInteractionControllerForAnimationController(navigationController: UINavigationController, animationController: UIViewControllerAnimatedTransitioning): UIViewControllerInteractiveTransitioning {
const owner = this.owner?.deref();
navigationControllerInteractionControllerForAnimationController(navigationController: UINavigationControllerImpl, animationController: UIViewControllerAnimatedTransitioning): UIViewControllerInteractiveTransitioning {
const owner = navigationController.owner;
if (owner) {
const state = SharedTransition.getState(owner.transitionId);
if (state?.instance?.iosInteractionDismiss) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/ui/gestures/index.ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class UIGestureRecognizerDelegateImpl extends NSObject implements UIGestureRecog
return false;
}
}
const recognizerDelegateInstance: UIGestureRecognizerDelegateImpl = <UIGestureRecognizerDelegateImpl>UIGestureRecognizerDelegateImpl.new();
const recognizerDelegateInstance = <UIGestureRecognizerDelegateImpl>UIGestureRecognizerDelegateImpl.new();

@NativeClass
class UIGestureRecognizerImpl extends NSObject {
Expand Down
Loading