From 9ac7496ed59afc58a38ec3b1793001f3cbbcfbd5 Mon Sep 17 00:00:00 2001 From: Topher Fangio Date: Wed, 26 Aug 2015 13:47:24 -0500 Subject: [PATCH] fix(tabs): Fix 0-height animation on iOS devices. On iOS devices, when switching between tabs, the height would jump to 0, then animate to the proper place causing a bad glitch. Fixes #4339. Closes #4341. --- src/components/tabs/js/tabsController.js | 46 ++++++++++++++++++------ src/components/tabs/tabs.scss | 3 -- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/components/tabs/js/tabsController.js b/src/components/tabs/js/tabsController.js index f83cb4155cb..dd133476807 100644 --- a/src/components/tabs/js/tabsController.js +++ b/src/components/tabs/js/tabsController.js @@ -6,7 +6,7 @@ angular * @ngInject */ function MdTabsController ($scope, $element, $window, $mdConstant, $mdTabInkRipple, - $mdUtil, $animate, $attrs, $compile, $mdTheming) { + $mdUtil, $animateCss, $attrs, $compile, $mdTheming) { // define private properties var ctrl = this, locked = false, @@ -635,17 +635,41 @@ function MdTabsController ($scope, $element, $window, $mdConstant, $mdTabInkRipp newHeight = contentHeight + tabsHeight, currentHeight = $element.prop('clientHeight'); if (currentHeight === newHeight) return; + + // Lock during animation so the user can't change tabs locked = true; - $animate - .animate( - $element, - { height: currentHeight + 'px' }, - { height: newHeight + 'px' } - ) - .then(function () { - $element.css('height', ''); - locked = false; - }); + + var fromHeight = { height: currentHeight + 'px'}, + toHeight = { height: newHeight + 'px' }; + + // Set the height to the current, specific pixel height to fix a bug on iOS where the height + // first animates to 0, then back to the proper height causing a visual glitch + $element.css(fromHeight); + + // Animate the height from the old to the new + $animateCss($element, { + from: fromHeight, + to: toHeight, + easing: 'cubic-bezier(0.35, 0, 0.25, 1)', + duration: 0.5 + }).start().done(function () { + // Then (to fix the same iOS issue as above), disable transitions and remove the specific + // pixel height so the height can size with browser width/content changes, etc. + $element.css({ + transition: 'none', + height: '' + }); + + // In the next tick, re-allow transitions (if we do it all at once, $element.css is "smart" + // enough to batch it for us instead of doing it immediately, which undoes the original + // transition: none) + $mdUtil.nextTick(function() { + $element.css('transition', ''); + }); + + // And unlock so tab changes can occur + locked = false; + }); } /** diff --git a/src/components/tabs/tabs.scss b/src/components/tabs/tabs.scss index 12008df06f7..d19456368cd 100644 --- a/src/components/tabs/tabs.scss +++ b/src/components/tabs/tabs.scss @@ -31,9 +31,6 @@ md-tabs { overflow: hidden; position: relative; flex-shrink: 0; - &.ng-animate { - transition: height $swift-ease-in-out-duration $swift-ease-in-out-timing-function; - } &:not(.md-no-tab-content):not(.md-dynamic-height) { min-height: 200 + $tabs-header-height; }