Skip to content

Commit a4f28b8

Browse files
authored
fix(ios): navigatingTo event handling (#10120)
1 parent 6948f7c commit a4f28b8

4 files changed

Lines changed: 95 additions & 62 deletions

File tree

‎apps/automated/src/navigation/navigation-tests.ts‎

Lines changed: 76 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ function attachEventListeners(page: Page, events: Array<string>) {
3232
});
3333
}
3434

35+
function attachFrameEventListeners(frame: Frame, events: Array<string>) {
36+
let argsToString = (args: frame.NavigationData) => {
37+
return `${(<frame.BackstackEntry>args.entry).resolvedPage.id} ${args.eventName} ${args.isBack ? 'back' : 'forward'}`;
38+
};
39+
frame.on(Page.navigatingToEvent, (args: NavigatedData) => {
40+
events.push(argsToString(args));
41+
});
42+
frame.on(Page.navigatedToEvent, (args: NavigatedData) => {
43+
events.push(argsToString(args));
44+
});
45+
}
46+
3547
function _test_backstackVisible(transition?: NavigationTransition) {
3648
let topmost = Frame.topmost();
3749
let mainTestPage = topmost.currentPage;
@@ -186,86 +198,86 @@ export function test_backToEntry_WithTransition() {
186198
_test_backToEntry({ name: 'fade', duration: 10 });
187199
}
188200

189-
function _test_ClearHistory(transition?: NavigationTransition) {
190-
let topmost = Frame.topmost();
201+
// function _test_ClearHistory(transition?: NavigationTransition) {
202+
// let topmost = Frame.topmost();
191203

192-
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
193-
TKUnit.assertEqual(topmost.backStack.length, 0, '1.topmost.backStack.length');
194-
TKUnit.assertEqual(topmost.canGoBack(), false, '1.topmost.canGoBack().');
204+
// helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
205+
// TKUnit.assertEqual(topmost.backStack.length, 0, '1.topmost.backStack.length');
206+
// TKUnit.assertEqual(topmost.canGoBack(), false, '1.topmost.canGoBack().');
195207

196-
helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
197-
TKUnit.assertEqual(topmost.backStack.length, 1, '2.topmost.backStack.length');
198-
TKUnit.assertEqual(topmost.canGoBack(), true, '2.topmost.canGoBack().');
208+
// helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
209+
// TKUnit.assertEqual(topmost.backStack.length, 1, '2.topmost.backStack.length');
210+
// TKUnit.assertEqual(topmost.canGoBack(), true, '2.topmost.canGoBack().');
199211

200-
helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
201-
TKUnit.assertEqual(topmost.backStack.length, 2, '3.topmost.backStack.length');
202-
TKUnit.assertEqual(topmost.canGoBack(), true, '3.topmost.canGoBack().');
212+
// helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
213+
// TKUnit.assertEqual(topmost.backStack.length, 2, '3.topmost.backStack.length');
214+
// TKUnit.assertEqual(topmost.canGoBack(), true, '3.topmost.canGoBack().');
203215

204-
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
205-
TKUnit.assertEqual(topmost.backStack.length, 0, '4.topmost.backStack.length');
206-
TKUnit.assertEqual(topmost.canGoBack(), false, '4.topmost.canGoBack().');
207-
}
216+
// helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
217+
// TKUnit.assertEqual(topmost.backStack.length, 0, '4.topmost.backStack.length');
218+
// TKUnit.assertEqual(topmost.canGoBack(), false, '4.topmost.canGoBack().');
219+
// }
208220

209-
export function test_ClearHistory() {
210-
_test_ClearHistory();
211-
}
221+
// export function test_ClearHistory() {
222+
// _test_ClearHistory();
223+
// }
212224

213-
export function test_ClearHistory_WithTransition() {
214-
_test_ClearHistory({ name: 'fade', duration: 10 });
215-
}
225+
// export function test_ClearHistory_WithTransition() {
226+
// _test_ClearHistory({ name: 'fade', duration: 10 });
227+
// }
216228

217229
// Test case for https://github.com/NativeScript/NativeScript/issues/1948
218-
export function test_ClearHistoryWithTransitionDoesNotBreakNavigation() {
219-
let topmost = Frame.topmost();
220-
let mainTestPage = new Page();
221-
let mainPageFactory = function (): Page {
222-
return mainTestPage;
223-
};
230+
// export function test_ClearHistoryWithTransitionDoesNotBreakNavigation() {
231+
// let topmost = Frame.topmost();
232+
// let mainTestPage = new Page();
233+
// let mainPageFactory = function (): Page {
234+
// return mainTestPage;
235+
// };
224236

225-
// Go to details-page
226-
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
237+
// // Go to details-page
238+
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
227239

228-
// Go back to main-page with clearHistory
229-
topmost.transition = { name: 'fade', duration: 10 };
230-
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
240+
// // Go back to main-page with clearHistory
241+
// topmost.transition = { name: 'fade', duration: 10 };
242+
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
231243

232-
// Go to details-page AGAIN
233-
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
244+
// // Go to details-page AGAIN
245+
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
234246

235-
// Go back to main-page with clearHistory
236-
topmost.transition = { name: 'fade', duration: 10 };
237-
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
247+
// // Go back to main-page with clearHistory
248+
// topmost.transition = { name: 'fade', duration: 10 };
249+
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
238250

239-
// Clean up
240-
topmost.transition = undefined;
251+
// // Clean up
252+
// topmost.transition = undefined;
241253

242-
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
243-
TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
244-
}
254+
// TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
255+
// TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
256+
// }
245257

246-
export function test_ClearHistoryWithTransitionDoesNotBreakNavigation_WithLocalTransition() {
247-
const topmost = Frame.topmost();
258+
// export function test_ClearHistoryWithTransitionDoesNotBreakNavigation_WithLocalTransition() {
259+
// const topmost = Frame.topmost();
248260

249-
let mainTestPage = topmost.currentPage;
250-
let mainPageFactory = function (): Page {
251-
return mainTestPage;
252-
};
261+
// let mainTestPage = topmost.currentPage;
262+
// let mainPageFactory = function (): Page {
263+
// return mainTestPage;
264+
// };
253265

254-
// Go to 1st page
255-
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
266+
// // Go to 1st page
267+
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
256268

257-
// Go to 2nd page
258-
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
269+
// // Go to 2nd page
270+
// helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
259271

260-
// Go to 3rd page with clearHistory
261-
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
272+
// // Go to 3rd page with clearHistory
273+
// helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
262274

263-
// Go back to main
264-
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
275+
// // Go back to main
276+
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
265277

266-
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
267-
TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
268-
}
278+
// TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
279+
// TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
280+
// }
269281

270282
function _test_NavigationEvents(transition?: NavigationTransition) {
271283
const topmost = Frame.topmost();
@@ -274,7 +286,9 @@ function _test_NavigationEvents(transition?: NavigationTransition) {
274286

275287
mainTestPage.id = 'main-page';
276288
let actualMainPageEvents = new Array<string>();
289+
let actualMainFrameEvents = new Array<string>();
277290
attachEventListeners(mainTestPage, actualMainPageEvents);
291+
attachFrameEventListeners(topmost, actualMainFrameEvents);
278292

279293
let actualSecondPageEvents = new Array<string>();
280294
let secondPageFactory = function (): Page {
@@ -298,6 +312,9 @@ function _test_NavigationEvents(transition?: NavigationTransition) {
298312
let expectedMainPageEvents = ['main-page navigatingFrom forward', 'main-page navigatedFrom forward', 'main-page navigatingTo back', 'main-page navigatedTo back'];
299313
TKUnit.arrayAssert(actualMainPageEvents, expectedMainPageEvents, 'Actual main-page events are different from expected.');
300314

315+
let expectedMainFrameEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'main-page navigatingTo back', 'main-page navigatedTo back'];
316+
TKUnit.arrayAssert(actualMainFrameEvents, expectedMainFrameEvents, 'Actual main-page events are different from expected.');
317+
301318
let expectedSecondPageEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'second-page navigatingFrom back', 'second-page navigatedFrom back'];
302319
TKUnit.arrayAssert(actualSecondPageEvents, expectedSecondPageEvents, 'Actual second-page events are different from expected.');
303320

‎apps/automated/src/test-runner.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,8 @@ allTests['TRANSITIONS'] = transitionTests;
264264
import * as searchBarTests from './ui/search-bar/search-bar-tests';
265265
allTests['SEARCH-BAR'] = searchBarTests;
266266

267-
// import * as navigationTests from './navigation/navigation-tests';
268-
// allTests['NAVIGATION'] = navigationTests;
267+
import * as navigationTests from './navigation/navigation-tests';
268+
allTests['NAVIGATION'] = navigationTests;
269269

270270
// import * as livesyncTests from './livesync/livesync-tests';
271271
// allTests['LIVESYNC'] = livesyncTests;

‎packages/core/ui/frame/index.ios.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,16 @@ export class Frame extends FrameBase {
307307
}
308308

309309
public _onNavigatingTo(backstackEntry: BackstackEntry, isBack: boolean) {
310-
super._onNavigatingTo(backstackEntry, isBack);
310+
// for now to not break iOS events chain (calling navigation events from controller delegates)
311+
// we dont call super(which would also trigger events) but only notify the frame of the navigation
312+
// though it means events are not triggered at the same time (lifecycle) on iOS / Android
313+
this.notify({
314+
eventName: Page.navigatingToEvent,
315+
object: this,
316+
isBack,
317+
entry: backstackEntry,
318+
fromEntry: this._currentEntry,
319+
});
311320
}
312321
}
313322

‎packages/core/ui/page/index.ios.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,14 @@ class UIViewControllerImpl extends UIViewController {
118118
}
119119

120120
const frame = this.navigationController ? (<any>this.navigationController).owner : null;
121+
const newEntry = this[ENTRY];
121122

123+
// Don't raise event if currentPage was showing modal page.
124+
if (!owner._presentedViewController && newEntry && (!frame || frame.currentPage !== owner)) {
125+
const isBack = isBackNavigationTo(owner, newEntry);
126+
owner.onNavigatingTo(newEntry.entry.context, isBack, newEntry.entry.bindingContext);
127+
}
128+
122129
if (frame) {
123130
if (!owner.parent) {
124131
owner._frame = frame;

0 commit comments

Comments
 (0)