Fixed navigation events

This commit is contained in:
Hristo Hristov
2016-03-18 11:53:36 +02:00
parent 7458880f28
commit 2cabf02215
19 changed files with 408 additions and 236 deletions

View File

@@ -231,7 +231,7 @@ export class Frame extends CustomLayoutView implements definition.Frame {
var entry = this._navigationQueue[0].entry;
var currentNavigationPage = entry.resolvedPage;
if (page !== currentNavigationPage) {
throw new Error(`Corrupted navigation stack; page: ${page.id}; currentNavigationPage: ${currentNavigationPage.id}`);
throw new Error(`Corrupted navigation stack; page: ${page}; currentNavigationPage: ${currentNavigationPage}`);
}
// remove completed operation.
@@ -275,7 +275,6 @@ export class Frame extends CustomLayoutView implements definition.Frame {
private performNavigation(navigationContext: NavigationContext) {
var navContext = navigationContext.entry;
this._onNavigatingTo(navContext, navigationContext.isBackNavigation);
// TODO: This should happen once navigation is completed.
if (navigationContext.entry.entry.clearHistory) {
@@ -285,15 +284,15 @@ export class Frame extends CustomLayoutView implements definition.Frame {
this._backStack.push(this._currentEntry);
}
this._onNavigatingTo(navContext, navigationContext.isBackNavigation);
this._navigateCore(navContext);
this._onNavigatedTo(navContext, false);
}
private performGoBack(navigationContext: NavigationContext) {
var navContext = navigationContext.entry;
this._onNavigatingTo(navContext, navigationContext.isBackNavigation);
this._goBackCore(navContext);
this._onNavigatedTo(navContext, true);
}
public _goBackCore(backstackEntry: definition.BackstackEntry) {
@@ -312,12 +311,6 @@ export class Frame extends CustomLayoutView implements definition.Frame {
backstackEntry.resolvedPage.onNavigatingTo(backstackEntry.entry.context, isBack);
}
public _onNavigatedTo(backstackEntry: definition.BackstackEntry, isBack: boolean) {
if (this.currentPage) {
this.currentPage.onNavigatedFrom(isBack);
}
}
public get animated(): boolean {
return this._animated;
}

View File

@@ -31,13 +31,16 @@ export class Frame extends frameCommon.Frame {
constructor() {
super();
this._ios = new iOSFrame(this);
// When there is a 40px high "in-call" status bar, nobody moves the navigationBar top from 20 to 40 and it remains underneath the status bar.
var that = this;
let frameRef = new WeakRef(this);
application.ios.addNotificationObserver(UIApplicationDidChangeStatusBarFrameNotification, (notification: NSNotification) => {
that._handleHigherInCallStatusBarIfNeeded();
if (this._ios.controller.owner.currentPage) {
this._ios.controller.owner.currentPage.requestLayout();
let frame = frameRef.get();
if (frame) {
frame._handleHigherInCallStatusBarIfNeeded();
if (frame.currentPage) {
frame.currentPage.requestLayout();
}
}
});
}
@@ -61,7 +64,7 @@ export class Frame extends frameCommon.Frame {
}
public _navigateCore(backstackEntry: definition.BackstackEntry) {
trace.write(`${this}._navigateCore(pageId: ${backstackEntry.resolvedPage.id}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry) }, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
trace.write(`${this}._navigateCore(page: ${backstackEntry.resolvedPage}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry)}, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
var viewController: UIViewController = backstackEntry.resolvedPage.ios;
if (!viewController) {
throw new Error("Required page does not have a viewController created.");
@@ -132,7 +135,7 @@ export class Frame extends frameCommon.Frame {
public _goBackCore(backstackEntry: definition.BackstackEntry) {
navDepth = backstackEntry[NAV_DEPTH];
trace.write(`${this}._goBackCore(pageId: ${backstackEntry.resolvedPage.id}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry) }, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
trace.write(`${this}._goBackCore(page: ${backstackEntry.resolvedPage}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry)}, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
if (!this._shouldSkipNativePop) {
var controller = backstackEntry.resolvedPage.ios;
@@ -292,6 +295,10 @@ export class Frame extends frameCommon.Frame {
}
}
public _onNavigatingTo(backstackEntry: definition.BackstackEntry, isBack: boolean) {
//
}
_handleHigherInCallStatusBarIfNeeded() {
let statusBarHeight = uiUtils.ios.getStatusBarHeight();
if (!this._ios ||
@@ -391,100 +398,6 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
}
}
public navigationControllerWillShowViewControllerAnimated(navigationController: UINavigationController, viewController: UIViewController, animated: boolean): void {
trace.write(`UINavigationControllerImpl.navigationControllerWillShowViewControllerAnimated(${navigationController}, ${viewController}, ${animated})`, trace.categories.NativeLifecycle);
// In this method we need to layout the new page otherwise page will be shown empty and update after that which is bad UX.
let frame = this._owner.get();
if (!frame) {
return;
}
let newEntry: definition.BackstackEntry = viewController[ENTRY];
let newPage = newEntry.resolvedPage;
if (!newPage.parent) {
if (!frame._currentEntry) {
// First navigation
frame._currentEntry = newEntry;
}
else {
frame._navigateToEntry = newEntry;
}
frame._addView(newPage);
frame.remeasureFrame();
}
else if (newPage.parent !== frame) {
throw new Error("Page is already shown on another frame.");
}
newPage.actionBar.update();
//HACK: https://github.com/NativeScript/NativeScript/issues/1021
viewController["willShowCalled"] = true;
}
public navigationControllerDidShowViewControllerAnimated(navigationController: UINavigationController, viewController: UIViewController, animated: boolean): void {
trace.write(`UINavigationControllerImpl.navigationControllerDidShowViewControllerAnimated(${navigationController}, ${viewController}, ${animated})`, trace.categories.NativeLifecycle);
//HACK: https://github.com/NativeScript/NativeScript/issues/1021
if (viewController["willShowCalled"] === undefined) {
return;
}
else {
viewController["willShowCalled"] = undefined;
}
let frame = this._owner.get();
if (!frame) {
return;
}
let newEntry: definition.BackstackEntry = viewController[ENTRY];
let newPage = newEntry.resolvedPage;
let backStack = frame.backStack;
let currentEntry = backStack.length > 0 ? backStack[backStack.length - 1] : null;
// This code check if navigation happened through UI (e.g. back button or swipe gesture).
// When calling goBack on frame isBack will be false.
let isBack: boolean = currentEntry && newEntry === currentEntry;
let currentNavigationContext;
let navigationQueue = (<any>frame)._navigationQueue;
for (let i = 0; i < navigationQueue.length; i++) {
if (navigationQueue[i].entry === newEntry) {
currentNavigationContext = navigationQueue[i];
break;
}
}
let isBackNavigation = currentNavigationContext ? currentNavigationContext.isBackNavigation : false;
if (isBack) {
try {
frame._shouldSkipNativePop = true;
frame.goBack();
}
finally {
frame._shouldSkipNativePop = false;
}
}
let page = frame.currentPage;
if (page && !navigationController.viewControllers.containsObject(page.ios)) {
frame._removeView(page);
}
frame._navigateToEntry = null;
frame._currentEntry = newEntry;
frame.remeasureFrame();
frame._updateActionBar(newPage);
// notify the page
newPage.onNavigatedTo(isBack || isBackNavigation);
frame._processNavigationQueue(newPage);
}
public supportedInterfaceOrientation(): number {
return UIInterfaceOrientationMask.UIInterfaceOrientationMaskAll;
}
@@ -672,25 +585,25 @@ function _getNativeTransition(navigationTransition: definition.NavigationTransit
return null;
}
export function _getNativeCurve(transition: definition.NavigationTransition) : UIViewAnimationCurve{
export function _getNativeCurve(transition: definition.NavigationTransition): UIViewAnimationCurve {
if (transition.curve) {
switch (transition.curve) {
case enums.AnimationCurve.easeIn:
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveEaseIn.", trace.categories.Transition);
return UIViewAnimationCurve.UIViewAnimationCurveEaseIn;
case enums.AnimationCurve.easeOut:
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveEaseOut.", trace.categories.Transition);
return UIViewAnimationCurve.UIViewAnimationCurveEaseOut;
case enums.AnimationCurve.easeInOut:
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveEaseInOut.", trace.categories.Transition);
return UIViewAnimationCurve.UIViewAnimationCurveEaseInOut;
case enums.AnimationCurve.linear:
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveLinear.", trace.categories.Transition);
return UIViewAnimationCurve.UIViewAnimationCurveLinear;
default:
trace.write("Transition curve resolved to original: " + transition.curve, trace.categories.Transition);
return transition.curve;
}
switch (transition.curve) {
case enums.AnimationCurve.easeIn:
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveEaseIn.", trace.categories.Transition);
return UIViewAnimationCurve.UIViewAnimationCurveEaseIn;
case enums.AnimationCurve.easeOut:
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveEaseOut.", trace.categories.Transition);
return UIViewAnimationCurve.UIViewAnimationCurveEaseOut;
case enums.AnimationCurve.easeInOut:
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveEaseInOut.", trace.categories.Transition);
return UIViewAnimationCurve.UIViewAnimationCurveEaseInOut;
case enums.AnimationCurve.linear:
trace.write("Transition curve resolved to UIViewAnimationCurve.UIViewAnimationCurveLinear.", trace.categories.Transition);
return UIViewAnimationCurve.UIViewAnimationCurveLinear;
default:
trace.write("Transition curve resolved to original: " + transition.curve, trace.categories.Transition);
return transition.curve;
}
}
return UIViewAnimationCurve.UIViewAnimationCurveEaseInOut;