How to give a visual indication of swipeable items?


#1

I’d like to give my app users a visual indication that items in a list can be swiped to reveal option buttons. Users are struggling to intuitively recognise that the items can be swiped.

I have other items in other lists that navigate to secondary pages and I indicate this to the user by adding a right-side arrow icon.

It would be really cool if there was a way to “bounce” the first item in the list after I have loaded the first page of data. What I mean by bounce would be to slide the item a little to the left revealing just a bit of the option buttons and then hide again (with a bounce-like animation).

Does anyone know how this could be achieved?


#2

Hi @avaxa,

you could do this in a fast and hacky way like this :wink:

In Controller.js call this method, once everything is loaded:

function revealOptionsPreview() {
      $timeout(function() {
        var ele = angular.element('.reveal')[0];
        var opt = angular.element('.item-options.invisible')[0];
        angular.element(opt).removeClass('invisible');
        angular.element(ele).addClass('sneakpeak');
        $timeout(function() {
          angular.element(opt).addClass('invisible');
          angular.element(ele).removeClass('sneakpeak');
        }, 1000);
      }, 1000);
    }

Add styling:

.sneakpeak .item-content {
  transform: translate3d(-50px, 0px, 0px) !important;
}

That’s it. Of course this is not “the angular” way. You could do the timings with CSS (instead of a 2nd timeout) as well i guess.


#3

personally i’d suggest a repeating CSS animation which does the transform. If you repeat it like 3 times, it should be clear that its swipable.


#4

Thanks @maxx0r and @dotzilla,

I took both of your suggestions and ended up with a directive and CSS animation that works well.

With the following directive implementation (in TypeScript):

public link(scope: ng.IScope, element: ng.IAugmentedJQuery, attributes: ng.IAttributes, controller: any, transclude: ng.ITranscludeFunction): void {
        scope.$on(Constants.Events.SCROLL_INFINITESCROLLCOMPLETE, (event: ng.IAngularEvent) => {
            this.$timeout(() => {
                let revealElement: Element = element[0].querySelector("ion-item");
                if (revealElement) {
                    let reveal: ng.IAugmentedJQuery = angular.element(revealElement);
                    reveal.addClass("bounce");
                    this.$timeout(() => {
                        // have to do this to hide the options element again for the sliding to work.
                        reveal.removeClass("bounce");
                    }, 1000);
                }
            }, 0);
        });
    }

and CSS styles:

@-webkit-keyframes bounce {
    0%, 20%, 50%, 80%, 100% {-webkit-transform: translateX(0);}
    40%, 60% {-webkit-transform: translateX(-10px);}
} 
@keyframes bounce {
    0%, 20%, 50%, 80%, 100% {transform: translateX(0);}
    40%, 60% {transform: translateX(-10px);}
} 
.bounce .item-content {
    -webkit-animation-name: bounce;
    animation-name: bounce;
    -webkit-animation-duration: 1s;
    animation-duration: 1s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
}
.bounce .item-options {
    visibility: inherit;
}

I can now add the ‘item-bounce’ attribute to ion-lists where I want the first item to bounce after loading the first page of data.

<ion-list can-swipe="true" item-bounce>