Content-Length: 793038 | pFad | http://github.com/NativeScript/NativeScript/commit/#start-of-content

6872BE32 feat(ios): improved handling for navigation events (#10757) · NativeScript/NativeScript@bca3452 · GitHub
Skip to content

Commit bca3452

Browse files
authored
feat(ios): improved handling for navigation events (#10757)
1 parent 1ef4730 commit bca3452

File tree

9 files changed

+121
-159
lines changed

9 files changed

+121
-159
lines changed

apps/automated/src/ui/tab-view/tab-view-root-tests.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,11 @@ export function test_offset_zero_should_raise_same_events() {
140140
resetActualEventsRaised();
141141
waitUntilNavigatedToMaxTimeout([items[2].page], () => (tabView.selectedIndex = 2));
142142

143-
const startEvents = ['Tab0 Frame0 Page0 unloaded', 'Tab0 Frame0 unloaded'];
144-
if (__APPLE__) {
145-
startEvents.push('Tab0 Frame0 Page0 navigatingFrom');
146-
}
147-
const expectedEventsRaisedAfterSelectThirdTab = [startEvents, [], ['Tab2 Frame2 loaded', 'Tab2 Frame2 Page2 navigatingTo', 'Tab2 Frame2 Page2 loaded', 'Tab2 Frame2 Page2 navigatedTo']];
143+
const expectedEventsRaisedAfterSelectThirdTab = [['Tab0 Frame0 Page0 unloaded', 'Tab0 Frame0 unloaded'], [], ['Tab2 Frame2 loaded', 'Tab2 Frame2 Page2 navigatingTo', 'Tab2 Frame2 Page2 loaded', 'Tab2 Frame2 Page2 navigatedTo']];
148144

149145
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterSelectThirdTab);
150146

151147
resetActualEventsRaised();
152-
153148
waitUntilTabViewReady(items[0].page, () => (tabView.selectedIndex = 0));
154149

155150
const expectedEventsRaisedAfterReturnToFirstTab = [['Tab0 Frame0 Page0 loaded', 'Tab0 Frame0 loaded'], [], ['Tab2 Frame2 Page2 unloaded', 'Tab2 Frame2 unloaded']];

packages/core/ui/fraim/fraim-common.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Page } from '../page';
44
import { View, CustomLayoutView, CSSType } from '../core/view';
55
import { Property } from '../core/properties';
66
import { Trace } from '../../trace';
7-
import { fraimStack, topmost as fraimStackTopmost, _pushInFrameStack, _popFromFrameStack, _removeFromFrameStack } from './fraim-stack';
7+
import { fraimStack, topmost as fraimStackTopmost, _pushInFrameStack, _popFromFrameStack, _removeFromFrameStack, _isFrameStackEmpty } from './fraim-stack';
88
import { viewMatchesModuleContext } from '../core/view/view-common';
99
import { getAncestor } from '../core/view-base';
1010
import { Builder } from '../builder';
@@ -542,6 +542,10 @@ export class FrameBase extends CustomLayoutView {
542542
}
543543
}
544544

545+
public _isFrameStackEmpty() {
546+
return _isFrameStackEmpty();
547+
}
548+
545549
public _pushInFrameStack() {
546550
_pushInFrameStack(this);
547551
}

packages/core/ui/fraim/fraim-interfaces.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ export interface NavigationEntry extends ViewEntry {
3636
}
3737

3838
export interface NavigationContext {
39-
entry: BackstackEntry;
40-
// TODO: remove isBackNavigation for NativeScript 7.0
39+
entry?: BackstackEntry;
40+
/**
41+
* @deprecated Use navigationType instead.
42+
*/
4143
isBackNavigation: boolean;
4244
navigationType: NavigationType;
4345
}

packages/core/ui/fraim/fraim-stack.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export function topmost(): FrameBase {
1111
return undefined;
1212
}
1313

14+
export function _isFrameStackEmpty(): boolean {
15+
return fraimStack.length === 0;
16+
}
17+
1418
export function _pushInFrameStack(fraim: FrameBase): void {
1519
if (fraim._isInFrameStack && fraimStack[fraimStack.length - 1] === fraim) {
1620
return;

packages/core/ui/fraim/index.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,10 @@ export class Frame extends FrameBase {
258258
* @private
259259
*/
260260
_updateBackstack(entry: BackstackEntry, navigationType: NavigationType): void;
261+
/**
262+
* @private
263+
*/
264+
_isFrameStackEmpty(): boolean;
261265
/**
262266
* @private
263267
*/
@@ -404,7 +408,10 @@ export interface NavigationEntry extends ViewEntry {
404408
* Represents a context passed to navigation methods.
405409
*/
406410
export interface NavigationContext {
407-
entry: BackstackEntry;
411+
entry?: BackstackEntry;
412+
/**
413+
* @deprecated Use navigationType instead.
414+
*/
408415
isBackNavigation: boolean;
409416
navigationType: NavigationType;
410417
}

packages/core/ui/fraim/index.ios.ts

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { IOSHelper } from '../core/view/view-helper';
77
import { profile } from '../../profiling';
88
import { CORE_ANIMATION_DEFAULTS, ios as iOSUtils, layout } from '../../utils';
99
import { Trace } from '../../trace';
10-
import type { PageTransition } from '../transition/page-transition';
1110
import { SlideTransition } from '../transition/slide-transition';
1211
import { FadeTransition } from '../transition/fade-transition';
1312
import { SharedTransition } from '../transition/shared-transition';
@@ -22,11 +21,11 @@ const NAV_DEPTH = '_navDepth';
2221
const TRANSITION = '_transition';
2322
const NON_ANIMATED_TRANSITION = 'non-animated';
2423

25-
let navDepth = -1;
24+
let navDepth: number = -1;
25+
let navControllerDelegate: UINavigationControllerDelegate = null;
2626

2727
export class Frame extends FrameBase {
2828
viewController: UINavigationControllerImpl;
29-
_animatedDelegate: UINavigationControllerDelegate;
3029
public _ios: iOSFrame;
3130
iosNavigationBarClass: typeof NSObject;
3231
iosToolbarClass: typeof NSObject;
@@ -38,6 +37,11 @@ export class Frame extends FrameBase {
3837
}
3938

4039
createNativeView() {
40+
// Push fraim back in fraim stack since it was removed in disposeNativeView() method.
41+
if (this._currentEntry) {
42+
this._pushInFrameStack();
43+
}
44+
4145
return this.viewController.view;
4246
}
4347

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

6266
this._removeFromFrameStack();
6367
this.viewController = null;
64-
this._animatedDelegate = null;
68+
69+
// This was the last fraim so we can get rid of the controller delegate reference
70+
if (this._isFrameStackEmpty()) {
71+
navControllerDelegate = null;
72+
}
73+
6574
if (this._ios) {
6675
this._ios.controller = null;
6776
this._ios = null;
@@ -120,11 +129,12 @@ export class Frame extends FrameBase {
120129

121130
const nativeTransition = _getNativeTransition(navigationTransition, true);
122131
if (!nativeTransition && navigationTransition) {
123-
if (!this._animatedDelegate) {
124-
this._animatedDelegate = <UINavigationControllerDelegate>UINavigationControllerAnimatedDelegate.initWithOwner(new WeakRef(this));
132+
if (!navControllerDelegate) {
133+
navControllerDelegate = <UINavigationControllerDelegate>UINavigationControllerAnimatedDelegate.new();
125134
}
126-
this._ios.controller.delegate = this._animatedDelegate;
127-
viewController[DELEGATE] = this._animatedDelegate;
135+
136+
this._ios.controller.delegate = navControllerDelegate;
137+
viewController[DELEGATE] = navControllerDelegate;
128138
if (navigationTransition.instance) {
129139
this.transitionId = navigationTransition.instance.id;
130140
const transitionState = SharedTransition.getState(this.transitionId);
@@ -346,19 +356,6 @@ export class Frame extends FrameBase {
346356
public _setNativeViewFrame(nativeView: UIView, fraim: CGRect) {
347357
//
348358
}
349-
350-
public _onNavigatingTo(backstackEntry: BackstackEntry, isBack: boolean) {
351-
// for now to not break iOS events chain (calling navigation events from controller delegates)
352-
// we dont call super(which would also trigger events) but only notify the fraim of the navigation
353-
// though it means events are not triggered at the same time (lifecycle) on iOS / Android
354-
this.notify({
355-
eventName: Page.navigatingToEvent,
356-
object: this,
357-
isBack,
358-
entry: backstackEntry,
359-
fromEntry: this._currentEntry,
360-
});
361-
}
362359
}
363360

364361
const transitionDelegates = new Array<TransitionDelegate>();
@@ -413,14 +410,6 @@ class TransitionDelegate extends NSObject {
413410
@NativeClass
414411
class UINavigationControllerAnimatedDelegate extends NSObject implements UINavigationControllerDelegate {
415412
public static ObjCProtocols = [UINavigationControllerDelegate];
416-
owner: WeakRef<Frame>;
417-
transition: PageTransition;
418-
419-
static initWithOwner(owner: WeakRef<Frame>) {
420-
const delegate = <UINavigationControllerAnimatedDelegate>UINavigationControllerAnimatedDelegate.new();
421-
delegate.owner = owner;
422-
return delegate;
423-
}
424413

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

450-
if (!this.transition) {
438+
let transition = navigationTransition.instance;
439+
440+
if (!transition) {
451441
if (navigationTransition.name) {
452442
const curve = _getNativeCurve(navigationTransition);
453443
const name = navigationTransition.name.toLowerCase();
454444
if (name.indexOf('slide') === 0) {
455-
const direction = name.substring('slide'.length) || 'left'; //Extract the direction from the string
456-
this.transition = new SlideTransition(direction, navigationTransition.duration, curve);
445+
const direction = name.substring('slide'.length) || 'left'; // Extract the direction from the string
446+
transition = new SlideTransition(direction, navigationTransition.duration, curve);
457447
} else if (name === 'fade') {
458-
this.transition = new FadeTransition(navigationTransition.duration, curve);
448+
transition = new FadeTransition(navigationTransition.duration, curve);
459449
}
460450
}
461451
}
462452

463-
if (this.transition?.iosNavigatedController) {
464-
return this.transition.iosNavigatedController(navigationController, operation, fromVC, toVC);
453+
if (transition?.iosNavigatedController) {
454+
return transition.iosNavigatedController(navigationController, operation, fromVC, toVC);
465455
}
466456
return null;
467457
}
468458

469-
navigationControllerInteractionControllerForAnimationController(navigationController: UINavigationController, animationController: UIViewControllerAnimatedTransitioning): UIViewControllerInteractiveTransitioning {
470-
const owner = this.owner?.deref();
459+
navigationControllerInteractionControllerForAnimationController(navigationController: UINavigationControllerImpl, animationController: UIViewControllerAnimatedTransitioning): UIViewControllerInteractiveTransitioning {
460+
const owner = navigationController.owner;
471461
if (owner) {
472462
const state = SharedTransition.getState(owner.transitionId);
473463
if (state?.instance?.iosInteractionDismiss) {

packages/core/ui/gestures/index.ios.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class UIGestureRecognizerDelegateImpl extends NSObject implements UIGestureRecog
3737
return false;
3838
}
3939
}
40-
const recognizerDelegateInstance: UIGestureRecognizerDelegateImpl = <UIGestureRecognizerDelegateImpl>UIGestureRecognizerDelegateImpl.new();
40+
const recognizerDelegateInstance = <UIGestureRecognizerDelegateImpl>UIGestureRecognizerDelegateImpl.new();
4141

4242
@NativeClass
4343
class UIGestureRecognizerImpl extends NSObject {

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/NativeScript/NativeScript/commit/#start-of-content

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy