Swipe to go back transition sometimes gets stuck

Users of my app reported a bug where the back button in the nav bar would suddenly stop working, trapping them in a breakaway page. The problem was very difficult to reproduce, but I eventually did, and discovered that the issue is that the transition animation that plays when swiping to go back gets stuck, rendering the back button unpressable.

Specifically, if I dig into the element tree, I can see that the two divs with class “nav-bar-block” have an attribute called “nav-bar” that is normally set to “active” and “cached”. When doing a swipe to go back, the active nav-bar-block changes to “leaving” and the cached nav-bar-block changes to “entering”. Normally when I release my finger so that it cancels it the transition, they will revert back to being “active” and “cached” after the animation concludes.

…But sometimes they don’t. It’s tricky to reproduce, but sometimes they will stay in their transitioning state, rendering any buttons in the nav bar unpressable, including the back button. Very short touches right on the screen’s left edge seem to trigger this with the greatest consistency. Sometimes you can even see that the transition has stopped part way through, with a little bit of the previous page showing and the active page pushed a few pixels to the right. It’s possible to get out of this stuck state by doing the swipe to go back gesture again, but that’s not something my users are likely to figure out on their own.

This is pretty clearly a bug in ionic that needs to be fixed. In the meantime, can anyone recommend a workaround for this? I’m aware I could disable the swipe to go back behavior, but I’d definitely prefer not to. If there’s some kind of temporary fix I could code into my app that allows me to keep this feature but avoid the bug, that would be great.

I think I am facing the same issue. no need to use swipe, but navigate between views quickly can trigger the issue sometimes.

please see the dom tree from the below screenshot when it happens: the “entering” views stays and there is just a blank dark screen . From the inspector, I can use location.reload() and it becomes OK . but for normal user, he/she will need to force stop the app and start again.

This issue only happens on IOS platform (IOS8 or IOS9 as I tested), and I am using ionic 1.1.0 with IOS9 patch.

I think i am having the same issue, posted it here.


If any solution please post.
Thank you.

I think I am facing the same issue. no need to use swipe, but navigate between views quickly can trigger the issue sometimes.

I’m looking a solution everywhere for this issue.
I can’t reproduce it every time but it appends a lot while navigating my app.
My ion-nav-buttons seem to be under the previous view buttons and users get blocked to that view as they can’t reload.
Did anyone find workaround for this ?

Sorry I’m so late to follow up on this, but I did find a workaround. Specifically I threw together some code that detects the stuck transition and fixes it. Note that this code is almost exactly a year old, so my app was using Ionic 1.1.0. I’m not sure if the same workaround will still work with a later version of Ionic. If it doesn’t though I bet it can be updated.

It works by waiting a small duration after a touch is released and checks some of Ionic’s divs to see if they’re in the stuck state, and fixes them if they are. I figured out which divs needed to be fixed by running my app on an iOS device or the iOS simulator and using Safari’s developer tools to inspect the web view in my app. I found that elements of class “nav-bar-block” would have an attribute “cached” or “active” when the page was not transitioning, and “entering” or “leaving” if it was. When the bug occurs, they never get set back to “cached” or “active”. So the code just checks to see what the value of that attribute is, and if it’s stuck as “entering” or “leaving” sets the attribute to “active” or “cached” respectively.

Anyway, here is the code. I originally had it in an application-level controller (i.e. the ng-controller directive was on the same element as ng-app) but it could also be placed in a service or something. Note that it also depends on underscore / lodash.

appModule.controller('appController', function ($rootScope, $timeout, $state) {
    var stateChanged = false;
    var touchEndTimeoutPromise = null;

    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
        /* jshint unused:vars */
        stateChanged = true;
    });
    
    // The following bit of code is a workaround for an iOS bug present in ionic 1.0.0 - 1.1.0, where a touch
    // on the left edge of the screen can cause a "swipe to go back" transition to get stuck, resulting in
    // the back button on the nav bar becoming unresponsive. This code detects that situation and corrects it.
    // Note that it has the unfortunate side effect of causing the nav bar to disappear during during the
    // transition when the user hits the back button. Nonetheless that's preferable to getting stuck on a
    // breakaway page.
    
    function checkForStuckTransition() {
        var navBarBlocks, navBarValues;
        
        // If we've changed states between when the touch was released and when this callback fired, we don't
        // need to check for anything.
        if (stateChanged) {
            return;
        }
        
        // The stuck animation occurs when the two 'nav-bar-block' elements have their 'nav-bar' attribute 
        // set to 'leaving' and 'entering' well after the touch has ended. We now check for that situation:
        
        navBarBlocks = document.getElementsByClassName("nav-bar-block");
        
        if (navBarBlocks.length !== 2) {
            return;
        }
        
        navBarValues = _.map(navBarBlocks, function(navBarBlock) {
            return navBarBlock.getAttribute('nav-bar');
        });
        
        if (navBarValues.indexOf('entering') !== -1 && navBarValues.indexOf('leaving') !== -1) {
            // To fix this, set the 'nav-bar' attribute back to 'cached' and 'active':
            console.log("Detected stuck transition... will now reset it.");
            
            if (navBarValues[0] === 'entering') {
                navBarBlocks[0].setAttribute('nav-bar', 'cached');
            } else {
                navBarBlocks[0].setAttribute('nav-bar', 'active');
            }
            
            if (navBarValues[1] === 'entering') {
                navBarBlocks[1].setAttribute('nav-bar', 'cached');
            } else {
                navBarBlocks[1].setAttribute('nav-bar', 'active');
            }
        }
    }
    
    function checkForStuckTransitionAfterDelay() {
        // Reset the state changed flag, so that if a state change occurs before the callback fires we'll
        // know about it:
        stateChanged = false;
        
        // If we've already made a timeout from before, cancel it since we're going to make another one:
        if (touchEndTimeoutPromise !== null) {
            $timeout.cancel(touchEndTimeoutPromise);
        }
        
        // Check if we're stuck 750 ms after a touch is lifted. This is enough time to be sure that any
        // non-stuck transition has finished and any change to the current state will have occurred, but
        // is a small enough interval that the user is unlikely to have tried to press the back button.
        touchEndTimeoutPromise = $timeout(function() {
            touchEndTimeoutPromise = null;
            checkForStuckTransition();
        }, 750);
    }
    
    // This only affects iOS:
    if (ionic.Platform.isIOS()) {
        // The 'swipe to go back' transition always gets stuck right after a touch is lifted:
        document.addEventListener('touchend', checkForStuckTransitionAfterDelay);
    }
});

Thanks a lot for the follow up, this bug is really annoying and very hard to reproduce.
I’ll try your solution and let you know how it goes.
Thanks again for your help !

I face this issue only in one plus 7 pro device which has only swipe left and right default as hardware back. Ionic app pages stuck and I swipe to back again many pages back buttons can be seen on the screen and many pages visible on the pages at a time