diff --git a/ionic/animations/ios-transition.ts b/ionic/animations/ios-transition.ts index e397cecad7..f8b113eb27 100644 --- a/ionic/animations/ios-transition.ts +++ b/ionic/animations/ios-transition.ts @@ -61,6 +61,7 @@ class IOSTransition extends Animation { .add(enteringNavbarItems) .add(enteringNavbarBg) .add(enteringBackButton); + enteringNavBar.before.addClass('show-navbar'); enteringTitle.fadeIn(); enteringNavbarItems.fadeIn(); diff --git a/ionic/animations/md-transition.ts b/ionic/animations/md-transition.ts index 7651ecc2f0..b3c2fb3d41 100644 --- a/ionic/animations/md-transition.ts +++ b/ionic/animations/md-transition.ts @@ -35,6 +35,10 @@ class MDTransition extends Animation { } if (enteringHasNavbar) { + let enteringNavBar = new Animation(enteringView.navbarRef()); + this.add(enteringNavBar); + enteringNavBar.before.addClass('show-navbar'); + let enteringBackButton = new Animation(enteringView.backBtnRef()); this.add(enteringBackButton); if (enteringView.enableBack()) { diff --git a/ionic/components/nav/nav-controller.ts b/ionic/components/nav/nav-controller.ts index f50e0298bb..52b99ebac9 100644 --- a/ionic/components/nav/nav-controller.ts +++ b/ionic/components/nav/nav-controller.ts @@ -581,16 +581,14 @@ export class NavController extends Ion { * @returns {any} TODO */ _transition(enteringView, leavingView, opts, done) { - let self = this; - if (enteringView === leavingView) { return done(enteringView); } if (!opts.animation) { - opts.animation = self.config.get('pageTransition'); + opts.animation = this.config.get('pageTransition'); } - if (self.config.get('animate') === false) { + if (this.config.get('animate') === false) { opts.animate = false; } @@ -600,100 +598,101 @@ export class NavController extends Ion { enteringView.loaded(); } - function beginTransition() { + this._stage(enteringView, opts, () => { if (enteringView.shouldDestroy) { // already marked as a view that will be destroyed, don't continue return done(enteringView); } - self._zone.runOutsideAngular(() => { - self._setZIndex(enteringView, leavingView, opts.direction); + this._zone.runOutsideAngular(() => { + this._setZIndex(enteringView, leavingView, opts.direction); enteringView.shouldDestroy = false; enteringView.shouldCache = false; - if (!opts.preload) { - enteringView.willEnter(); - leavingView.willLeave(); - } - - // set that the new view pushed on the stack is staged to be entering/leaving - // staged state is important for the transition to find the correct view - enteringView.state = STAGED_ENTERING_STATE; - leavingView.state = STAGED_LEAVING_STATE; - - // init the transition animation - opts.renderDelay = opts.transitionDelay || self.config.get('pageTransitionDelay'); - - let transAnimation = Animation.createTransition(self._getStagedEntering(), - self._getStagedLeaving(), - opts); - if (opts.animate === false) { - // force it to not animate the elements, just apply the "to" styles - transAnimation.clearDuration(); - transAnimation.duration(0); - } - - let duration = transAnimation.duration(); - let enableApp = (duration < 64); - // block any clicks during the transition and provide a - // fallback to remove the clickblock if something goes wrong - self.app.setEnabled(enableApp, duration); - self.setTransitioning(!enableApp, duration); - - if (!enableApp) { - // do a quick check for changes - // then detach the change detection during a transition - self._cd.detectChanges(); - self._cd.detach(); - } - - if (opts.pageType) { - transAnimation.before.addClass(opts.pageType); - } - - // start the transition - transAnimation.play(() => { - // transition has completed, update each view's state - enteringView.state = ACTIVE_STATE; - leavingView.state = CACHED_STATE; - - // dispose any views that shouldn't stay around - transAnimation.dispose(); + this._postRender(enteringView, opts, () => { if (!opts.preload) { - enteringView.didEnter(); - leavingView.didLeave(); + enteringView.willEnter(); + leavingView.willLeave(); } - // reattach the change detection - self._cd.reattach(); + // set that the new view pushed on the stack is staged to be entering/leaving + // staged state is important for the transition to find the correct view + enteringView.state = STAGED_ENTERING_STATE; + leavingView.state = STAGED_LEAVING_STATE; - self._zone.run(() => { - if (self.keyboard.isOpen()) { - self.keyboard.onClose(() => { - self._transComplete(); - done(enteringView); - }, 32); + // init the transition animation + opts.renderDelay = opts.transitionDelay || this.config.get('pageTransitionDelay'); - } else { - self._transComplete(); - done(enteringView); + let transAnimation = Animation.createTransition(this._getStagedEntering(), + this._getStagedLeaving(), + opts); + if (opts.animate === false) { + // force it to not animate the elements, just apply the "to" styles + transAnimation.clearDuration(); + transAnimation.duration(0); + } + + let duration = transAnimation.duration(); + let enableApp = (duration < 64); + // block any clicks during the transition and provide a + // fallback to remove the clickblock if something goes wrong + this.app.setEnabled(enableApp, duration); + this.setTransitioning(!enableApp, duration); + + if (!enableApp) { + // do a quick check for changes + // then detach the change detection during a transition + this._cd.detectChanges(); + this._cd.detach(); + } + + if (opts.pageType) { + transAnimation.before.addClass(opts.pageType); + } + + // start the transition + transAnimation.play(() => { + // transition has completed, update each view's state + enteringView.state = ACTIVE_STATE; + leavingView.state = CACHED_STATE; + + // dispose any views that shouldn't stay around + transAnimation.dispose(); + + if (!opts.preload) { + enteringView.didEnter(); + leavingView.didLeave(); } + + // reattach the change detection + this._cd.reattach(); + + this._zone.run(() => { + if (this.keyboard.isOpen()) { + this.keyboard.onClose(() => { + this._transComplete(); + done(enteringView); + }, 32); + + } else { + this._transComplete(); + done(enteringView); + } + }); }); }); }); - } - - self._stage(enteringView, beginTransition); + }); } /** * @private */ - _stage(viewCtrl, done) { + _stage(viewCtrl, opts, done) { if (viewCtrl.isLoaded() || viewCtrl.shouldDestroy) { // already compiled this view return done(); @@ -701,22 +700,21 @@ export class NavController extends Ion { // get the pane the NavController wants to use // the pane is where all this content will be placed into - this.loadPage(viewCtrl, null, () => { - + this.loadPage(viewCtrl, null, opts, () => { if (viewCtrl.onReady) { viewCtrl.onReady(() => { viewCtrl.loaded(); done(); }); + } else { viewCtrl.loaded(); done(); } - }); } - loadPage(viewCtrl, navbarContainerRef, done) { + loadPage(viewCtrl, navbarContainerRef, opts, done) { let providers = this.providers.concat(Injector.resolve([ provide(ViewController, {useValue: viewCtrl}), provide(NavParams, {useValue: viewCtrl.params}) @@ -756,6 +754,8 @@ export class NavController extends Ion { }); } + opts.postLoad && opts.postLoad(viewCtrl); + if (this._views.length === 1) { this._zone.runOutsideAngular(() => { rafFrames(38, () => { @@ -768,6 +768,17 @@ export class NavController extends Ion { }); } + _postRender(enteringView, opts, done) { + enteringView.postRender(); + + if (opts.animate === false) { + done(); + + } else { + rafFrames(2, done); + } + } + _setZIndex(enteringView, leavingView, direction) { let enteringPageRef = enteringView && enteringView.pageRef(); if (enteringPageRef) { @@ -841,7 +852,7 @@ export class NavController extends Ion { enteringView.willEnter(); // wait for the new view to complete setup - enteringView._stage(() => { + enteringView._stage(enteringView, {}, () => { this._zone.runOutsideAngular(() => { // set that the new view pushed on the stack is staged to be entering/leaving diff --git a/ionic/components/nav/view-controller.ts b/ionic/components/nav/view-controller.ts index f5f92c2c05..be708ca91c 100644 --- a/ionic/components/nav/view-controller.ts +++ b/ionic/components/nav/view-controller.ts @@ -161,6 +161,12 @@ export class ViewController { } } + postRender() { + // let navbar = this.getNavbar(); + // navbar && navbar.postRender(); + // ctrlFn(this, 'onPagePostRender'); + } + /** * The view is about to enter and become the active view. */ diff --git a/ionic/components/navbar/navbar.scss b/ionic/components/navbar/navbar.scss index 07bd13bc53..e41d28bcbe 100644 --- a/ionic/components/navbar/navbar.scss +++ b/ionic/components/navbar/navbar.scss @@ -6,6 +6,11 @@ ion-navbar.toolbar { display: flex; + transform: translate3d(-9999px, -9999px, 0); +} + +ion-navbar.toolbar.show-navbar { + transform: none; } .back-button { diff --git a/ionic/components/tabs/tab.ts b/ionic/components/tabs/tab.ts index d6a2117cfe..430c69bed8 100644 --- a/ionic/components/tabs/tab.ts +++ b/ionic/components/tabs/tab.ts @@ -104,11 +104,13 @@ export class Tab extends NavController { if (!this._loaded) { let opts = { animate: false, - preload: true + preload: true, + postLoad: (viewCtrl) => { + let navbar = viewCtrl.getNavbar(); + navbar && navbar.setHidden(true); + } }; - this.load(opts, () => { - this.hideNavbars(true); - }); + this.load(opts); } }, 1000 * this.index); } @@ -130,7 +132,7 @@ export class Tab extends NavController { /** * @private */ - loadPage(viewCtrl, navbarContainerRef, done) { + loadPage(viewCtrl, navbarContainerRef, opts, done) { // by default a page's navbar goes into the shared tab's navbar section navbarContainerRef = this.parent.navbarContainerRef; @@ -141,7 +143,7 @@ export class Tab extends NavController { navbarContainerRef = null; } - super.loadPage(viewCtrl, navbarContainerRef, () => { + super.loadPage(viewCtrl, navbarContainerRef, opts, () => { if (viewCtrl.instance) { viewCtrl.instance._tabSubPage = isTabSubPage; }