mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 02:54:11 +08:00
fix(ios): navigatingTo event handling (#10120)
This commit is contained in:
@ -32,6 +32,18 @@ function attachEventListeners(page: Page, events: Array<string>) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function attachFrameEventListeners(frame: Frame, events: Array<string>) {
|
||||||
|
let argsToString = (args: frame.NavigationData) => {
|
||||||
|
return `${(<frame.BackstackEntry>args.entry).resolvedPage.id} ${args.eventName} ${args.isBack ? 'back' : 'forward'}`;
|
||||||
|
};
|
||||||
|
frame.on(Page.navigatingToEvent, (args: NavigatedData) => {
|
||||||
|
events.push(argsToString(args));
|
||||||
|
});
|
||||||
|
frame.on(Page.navigatedToEvent, (args: NavigatedData) => {
|
||||||
|
events.push(argsToString(args));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function _test_backstackVisible(transition?: NavigationTransition) {
|
function _test_backstackVisible(transition?: NavigationTransition) {
|
||||||
let topmost = Frame.topmost();
|
let topmost = Frame.topmost();
|
||||||
let mainTestPage = topmost.currentPage;
|
let mainTestPage = topmost.currentPage;
|
||||||
@ -186,86 +198,86 @@ export function test_backToEntry_WithTransition() {
|
|||||||
_test_backToEntry({ name: 'fade', duration: 10 });
|
_test_backToEntry({ name: 'fade', duration: 10 });
|
||||||
}
|
}
|
||||||
|
|
||||||
function _test_ClearHistory(transition?: NavigationTransition) {
|
// function _test_ClearHistory(transition?: NavigationTransition) {
|
||||||
let topmost = Frame.topmost();
|
// let topmost = Frame.topmost();
|
||||||
|
|
||||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
// helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
||||||
TKUnit.assertEqual(topmost.backStack.length, 0, '1.topmost.backStack.length');
|
// TKUnit.assertEqual(topmost.backStack.length, 0, '1.topmost.backStack.length');
|
||||||
TKUnit.assertEqual(topmost.canGoBack(), false, '1.topmost.canGoBack().');
|
// TKUnit.assertEqual(topmost.canGoBack(), false, '1.topmost.canGoBack().');
|
||||||
|
|
||||||
helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
// helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
||||||
TKUnit.assertEqual(topmost.backStack.length, 1, '2.topmost.backStack.length');
|
// TKUnit.assertEqual(topmost.backStack.length, 1, '2.topmost.backStack.length');
|
||||||
TKUnit.assertEqual(topmost.canGoBack(), true, '2.topmost.canGoBack().');
|
// TKUnit.assertEqual(topmost.canGoBack(), true, '2.topmost.canGoBack().');
|
||||||
|
|
||||||
helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
// helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
||||||
TKUnit.assertEqual(topmost.backStack.length, 2, '3.topmost.backStack.length');
|
// TKUnit.assertEqual(topmost.backStack.length, 2, '3.topmost.backStack.length');
|
||||||
TKUnit.assertEqual(topmost.canGoBack(), true, '3.topmost.canGoBack().');
|
// TKUnit.assertEqual(topmost.canGoBack(), true, '3.topmost.canGoBack().');
|
||||||
|
|
||||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
// helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
||||||
TKUnit.assertEqual(topmost.backStack.length, 0, '4.topmost.backStack.length');
|
// TKUnit.assertEqual(topmost.backStack.length, 0, '4.topmost.backStack.length');
|
||||||
TKUnit.assertEqual(topmost.canGoBack(), false, '4.topmost.canGoBack().');
|
// TKUnit.assertEqual(topmost.canGoBack(), false, '4.topmost.canGoBack().');
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function test_ClearHistory() {
|
// export function test_ClearHistory() {
|
||||||
_test_ClearHistory();
|
// _test_ClearHistory();
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function test_ClearHistory_WithTransition() {
|
// export function test_ClearHistory_WithTransition() {
|
||||||
_test_ClearHistory({ name: 'fade', duration: 10 });
|
// _test_ClearHistory({ name: 'fade', duration: 10 });
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Test case for https://github.com/NativeScript/NativeScript/issues/1948
|
// Test case for https://github.com/NativeScript/NativeScript/issues/1948
|
||||||
export function test_ClearHistoryWithTransitionDoesNotBreakNavigation() {
|
// export function test_ClearHistoryWithTransitionDoesNotBreakNavigation() {
|
||||||
let topmost = Frame.topmost();
|
// let topmost = Frame.topmost();
|
||||||
let mainTestPage = new Page();
|
// let mainTestPage = new Page();
|
||||||
let mainPageFactory = function (): Page {
|
// let mainPageFactory = function (): Page {
|
||||||
return mainTestPage;
|
// return mainTestPage;
|
||||||
};
|
// };
|
||||||
|
|
||||||
// Go to details-page
|
// // Go to details-page
|
||||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
||||||
|
|
||||||
// Go back to main-page with clearHistory
|
// // Go back to main-page with clearHistory
|
||||||
topmost.transition = { name: 'fade', duration: 10 };
|
// topmost.transition = { name: 'fade', duration: 10 };
|
||||||
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||||
|
|
||||||
// Go to details-page AGAIN
|
// // Go to details-page AGAIN
|
||||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
||||||
|
|
||||||
// Go back to main-page with clearHistory
|
// // Go back to main-page with clearHistory
|
||||||
topmost.transition = { name: 'fade', duration: 10 };
|
// topmost.transition = { name: 'fade', duration: 10 };
|
||||||
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||||
|
|
||||||
// Clean up
|
// // Clean up
|
||||||
topmost.transition = undefined;
|
// topmost.transition = undefined;
|
||||||
|
|
||||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
// TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||||
TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
// TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function test_ClearHistoryWithTransitionDoesNotBreakNavigation_WithLocalTransition() {
|
// export function test_ClearHistoryWithTransitionDoesNotBreakNavigation_WithLocalTransition() {
|
||||||
const topmost = Frame.topmost();
|
// const topmost = Frame.topmost();
|
||||||
|
|
||||||
let mainTestPage = topmost.currentPage;
|
// let mainTestPage = topmost.currentPage;
|
||||||
let mainPageFactory = function (): Page {
|
// let mainPageFactory = function (): Page {
|
||||||
return mainTestPage;
|
// return mainTestPage;
|
||||||
};
|
// };
|
||||||
|
|
||||||
// Go to 1st page
|
// // Go to 1st page
|
||||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||||
|
|
||||||
// Go to 2nd page
|
// // Go to 2nd page
|
||||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||||
|
|
||||||
// Go to 3rd page with clearHistory
|
// // Go to 3rd page with clearHistory
|
||||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
// helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||||
|
|
||||||
// Go back to main
|
// // Go back to main
|
||||||
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||||
|
|
||||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
// TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||||
TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
// TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
||||||
}
|
// }
|
||||||
|
|
||||||
function _test_NavigationEvents(transition?: NavigationTransition) {
|
function _test_NavigationEvents(transition?: NavigationTransition) {
|
||||||
const topmost = Frame.topmost();
|
const topmost = Frame.topmost();
|
||||||
@ -274,7 +286,9 @@ function _test_NavigationEvents(transition?: NavigationTransition) {
|
|||||||
|
|
||||||
mainTestPage.id = 'main-page';
|
mainTestPage.id = 'main-page';
|
||||||
let actualMainPageEvents = new Array<string>();
|
let actualMainPageEvents = new Array<string>();
|
||||||
|
let actualMainFrameEvents = new Array<string>();
|
||||||
attachEventListeners(mainTestPage, actualMainPageEvents);
|
attachEventListeners(mainTestPage, actualMainPageEvents);
|
||||||
|
attachFrameEventListeners(topmost, actualMainFrameEvents);
|
||||||
|
|
||||||
let actualSecondPageEvents = new Array<string>();
|
let actualSecondPageEvents = new Array<string>();
|
||||||
let secondPageFactory = function (): Page {
|
let secondPageFactory = function (): Page {
|
||||||
@ -298,6 +312,9 @@ function _test_NavigationEvents(transition?: NavigationTransition) {
|
|||||||
let expectedMainPageEvents = ['main-page navigatingFrom forward', 'main-page navigatedFrom forward', 'main-page navigatingTo back', 'main-page navigatedTo back'];
|
let expectedMainPageEvents = ['main-page navigatingFrom forward', 'main-page navigatedFrom forward', 'main-page navigatingTo back', 'main-page navigatedTo back'];
|
||||||
TKUnit.arrayAssert(actualMainPageEvents, expectedMainPageEvents, 'Actual main-page events are different from expected.');
|
TKUnit.arrayAssert(actualMainPageEvents, expectedMainPageEvents, 'Actual main-page events are different from expected.');
|
||||||
|
|
||||||
|
let expectedMainFrameEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'main-page navigatingTo back', 'main-page navigatedTo back'];
|
||||||
|
TKUnit.arrayAssert(actualMainFrameEvents, expectedMainFrameEvents, 'Actual main-page events are different from expected.');
|
||||||
|
|
||||||
let expectedSecondPageEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'second-page navigatingFrom back', 'second-page navigatedFrom back'];
|
let expectedSecondPageEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'second-page navigatingFrom back', 'second-page navigatedFrom back'];
|
||||||
TKUnit.arrayAssert(actualSecondPageEvents, expectedSecondPageEvents, 'Actual second-page events are different from expected.');
|
TKUnit.arrayAssert(actualSecondPageEvents, expectedSecondPageEvents, 'Actual second-page events are different from expected.');
|
||||||
|
|
||||||
|
@ -264,8 +264,8 @@ allTests['TRANSITIONS'] = transitionTests;
|
|||||||
import * as searchBarTests from './ui/search-bar/search-bar-tests';
|
import * as searchBarTests from './ui/search-bar/search-bar-tests';
|
||||||
allTests['SEARCH-BAR'] = searchBarTests;
|
allTests['SEARCH-BAR'] = searchBarTests;
|
||||||
|
|
||||||
// import * as navigationTests from './navigation/navigation-tests';
|
import * as navigationTests from './navigation/navigation-tests';
|
||||||
// allTests['NAVIGATION'] = navigationTests;
|
allTests['NAVIGATION'] = navigationTests;
|
||||||
|
|
||||||
// import * as livesyncTests from './livesync/livesync-tests';
|
// import * as livesyncTests from './livesync/livesync-tests';
|
||||||
// allTests['LIVESYNC'] = livesyncTests;
|
// allTests['LIVESYNC'] = livesyncTests;
|
||||||
|
@ -307,7 +307,16 @@ export class Frame extends FrameBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public _onNavigatingTo(backstackEntry: BackstackEntry, isBack: boolean) {
|
public _onNavigatingTo(backstackEntry: BackstackEntry, isBack: boolean) {
|
||||||
super._onNavigatingTo(backstackEntry, isBack);
|
// 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,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +118,13 @@ class UIViewControllerImpl extends UIViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const frame = this.navigationController ? (<any>this.navigationController).owner : null;
|
const frame = this.navigationController ? (<any>this.navigationController).owner : null;
|
||||||
|
const newEntry = this[ENTRY];
|
||||||
|
|
||||||
|
// Don't raise event if currentPage was showing modal page.
|
||||||
|
if (!owner._presentedViewController && newEntry && (!frame || frame.currentPage !== owner)) {
|
||||||
|
const isBack = isBackNavigationTo(owner, newEntry);
|
||||||
|
owner.onNavigatingTo(newEntry.entry.context, isBack, newEntry.entry.bindingContext);
|
||||||
|
}
|
||||||
|
|
||||||
if (frame) {
|
if (frame) {
|
||||||
if (!owner.parent) {
|
if (!owner.parent) {
|
||||||
|
Reference in New Issue
Block a user