Skip to content
This repository was archived by the owner on May 4, 2022. It is now read-only.

ion-reorder in ion-list drags whole screen rather than item #224

Open
jgw96 opened this issue Mar 13, 2017 · 18 comments
Open

ion-reorder in ion-list drags whole screen rather than item #224

jgw96 opened this issue Mar 13, 2017 · 18 comments

Comments

@jgw96
Copy link
Contributor

jgw96 commented Mar 13, 2017

From @LucasMcL on March 12, 2017 20:59

Ionic version: (check one with "x")
[X] 1.x
[ ] 2.x

I'm submitting a ... (check one with "x")
[X] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/

Current behavior:
The reordering functionality built directly into via is not working properly on my android phone. When I press and hold the reorder button, then move up or down, it scrolls the whole screen rather than the individual item. Thus, you can't actually reorder the item.

Expected behavior:
I expect the screen to not move unless the item I'm scrolling gets near the top or bottom, at which point the screen should scroll in that direction.

Steps to reproduce:
I've included a codepen with code similar to my project. It seems to work in code pen, but when I pull it down and run it on my phone, it recreates the issue. I've also included a gif that shows the issue. My phone is a Moto X Pure Edition running android operating system 6.0.

Related code:
https://media.giphy.com/media/xUPGcCT4rHhzgVKzJK/giphy.gif
http://codepen.io/LucasMcL/pen/ryemMJ

Other information:

Similar post in forums: https://forum.ionicframework.com/t/ionic-reorder-poor-responsiveness-on-android-phone/81886
My list with delete and reorder buttons is very similar to the official ionic example on codepen: https://codepen.io/ionic/pen/JsHjf.

Things I've tried:
-Reducing the size of the objects in the array that comprises the
-Showing just the reorder button and not delete at the same time
-Using collection-repeat

Ionic info: (run ionic info from a terminal/cmd prompt and paste output below):

******************************************************
 Dependency warning - for the CLI to run correctly,
 it is highly recommended to install/upgrade the following:

 Install ios-sim to deploy iOS applications.`npm install -g ios-sim` (may require sudo)
 Install ios-deploy to deploy iOS applications to devices.  `npm install -g ios-deploy` (may require sudo)

******************************************************

Your system information:

Cordova CLI: 6.5.0
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
ios-deploy version: Not installed
ios-sim version: Not installed
OS: OS X El Capitan
Node Version: v7.4.0
Xcode version: Not installed

Copied from original issue: ionic-team/ionic-framework#10747

@KamranKawish
Copy link

Have you found any solutions for the problem, I seem to be having the same problem

@LucasMcL
Copy link

I have not. I've had this issue for weeks and have been unable to solve it. I'm hoping the good folks at Ionic are able to help out.

@KamranKawish
Copy link

It seems to cause this problem when I use ion-scroll. On a normal ion-content with scroll it works like it is supposed to

@KamranKawish
Copy link

KamranKawish commented Mar 17, 2017

here is how solved the problem. create a css rule ".noscroll { pointer-events: none; }" and then use ng-class to apply this rule to your ion-scroll with the same boolean you use for show-reorder. I hope it helps

@gylippus
Copy link

@KamranKawish can you clarify the css that you are describing? Not sure I'm following the syntax you use.

@KamranKawish
Copy link

@gylippus
Sorry there was a typo mistake, I updated my comment.

@LucasMcL
Copy link

@KamranKawish My ion-reorder isn't in an ion-scroll; it is inside a normal ion-content. In fact, it is almost identical to the official example here: https://codepen.io/ionic/pen/JsHjf. I will try manually toggling the scroll with a boolean, though.

@gylippus
Copy link

@LucasMcL I tried what was suggested using css to select and apply pointer-events: none to the ion-scroll when the reorder was active. I didn't help for me.

@LucasMcL
Copy link

LucasMcL commented Mar 19, 2017

@KamranKawish that worked for me! Thanks so much! I modified it a little bit. Here's my code:

HTML:

<ion-content class="padding" ng-class="{noscroll: reordering}">

...

    <ion-list show-reorder="editMode", show-delete="editMode">

      <ion-item ng-repeat="item in tracks">
        <ion-delete-button class="ion-minus-circled" ng-click="onItemDelete(item)">
        </ion-delete-button>
        <h3>{{item.track.name}}</h3>
        <p>{{item.track.artists[0].name}} • {{item.track.album.name}}</p>
        <ion-reorder-button class="ion-navicon" on-reorder="onItemMove(item, $fromIndex, 
          $toIndex)"
          on-touch="onReorderButtonTouch()"
          on-release="onReorderButtonRelease()"></ion-reorder-button>
      </ion-item>

    </ion-list>

JS:
` $scope.onReorderButtonTouch = function() {
$scope.reordering = true
}

$scope.onReorderButtonRelease = function() {
$scope.reordering = false
}`

CSS:
.noscroll { pointer-events: none; }

I needed to still be able to scroll when in edit mode. I just needed it to not scroll specifically when the user was reordering an item. So, I toggle a variable on touch and on release of the reorder button itself. I use that variable to apply the CSS that @KamranKawish provided.

@gylippus
Copy link

@LucasMcL where did you attach the onReorderButtonTouch and onReorderButtonRelease in the HTML?

@LucasMcL
Copy link

@gylippus Fair question. I've updated my comment with some more code. Maybe too much code. But there you go. Towards the bottom, you can see that the onReorderButtonTouch and onReorderButtonRelease functions are called in the on-touch and on-release directives of the actual ion-reorder button.

@gylippus
Copy link

@LucasMcL thanks for that. I do see a pretty solid improvement in the browser while testing, but I'm still hitting issues where the dragging item is just staying fixed to the top or bottom causing the whole list to continuously scroll on an actual Android device. I'm trying to look into some of the thresholds for boundaries at the moment.

@LucasMcL
Copy link

@gylippus let me know what you find. It's working for me, but I do find that it's a little bit hard to control the rate at which its scrolls. It often scrolls REALLY fast when the reordered item is at the top or bottom of the screen. I would be interested in learning how to adjust those thresholds a little.

@freddiescott
Copy link

Thank you @LucasMcL , this worked for me !

@KamranKawish
Copy link

KamranKawish commented May 27, 2017

you can use $ionicScrollDelegate.getScrollView().options.scrollingY=false; in you touch and release functions but beware that it will completely freeze the scroll and will not scroll up/down if your item has reached the top/bottom of the page

@KamranKawish
Copy link

$ionicScrollDelegate.$getByHandle('handleName').getScrollView().options.scrollingY if you are using a delegate handle

@pfiaux
Copy link

pfiaux commented Jul 12, 2017

It looks like the problem comes from the listview drag implementation (which tries to scroll and runs call backs even if scroll is disabled (trouble some with native scroll):

ionic.requestAnimationFrame(function() {

if (e.gesture.deltaY < 0 && pixelsPastTop > 0 && scrollY > 0) {
  this.scrollView.scrollBy(null, -pixelsPastTop);
  //Trigger another drag so the scrolling keeps going
  ionic.requestAnimationFrame(function() {
    self.drag(e);
  });
}
if (e.gesture.deltaY > 0 && pixelsPastBottom > 0) {
  if (scrollY < this.scrollView.getScrollMax().top) {
    this.scrollView.scrollBy(null, pixelsPastBottom);
    //Trigger another drag so the scrolling keeps going
    ionic.requestAnimationFrame(function() {
      self.drag(e);
    });
  }
}

basically if you go past the edge you need to keep scrolling, so it calls itself with the event.

However the events are never marked as stale and there's no way to reset this scrolling until it his the top/bottom. It's not infinite recursion but it's missing a bottom condition (drag is no longer past bottom or top).

@pfiaux
Copy link

pfiaux commented Jul 12, 2017

I replaced the code above and I can now stop scrolling:

      if (!e.stale) {
        if (pixelsPastBottom <= 0 && pixelsPastTop <= 0) {
          this._currentDrag.overScrollPixels = 0;
        }
        else if (e.gesture.deltaY < 0 && pixelsPastTop > 0 && scrollY > 0) {
          this._currentDrag.overScrollPixels = -pixelsPastTop;
        }
        else if (e.gesture.deltaY > 0 && pixelsPastBottom > 0 && scrollY < this.scrollView.getScrollMax().top) {
          this._currentDrag.overScrollPixels = pixelsPastBottom;
        }
      }
      // Don't process this event again!
      e.stale = true;

      if (this._currentDrag.overScrollPixels !== 0) {
        this.scrollView.scrollBy(null, this._currentDrag.overScrollPixels);

        //Trigger another drag so the scrolling keeps going
        // until overScrollPixels hits 0
        setTimeout(function() {
          ionic.requestAnimationFrame(function() {
            self.drag(e);
          });
        }, 10);
      }

It's still not perfect and can scroll too quickly to the top/bottom (before a drag without scroll event can be handled). Possible improvements:

  • The timeout helps avoiding too many animation frames but should probably be higher
  • The still no maximum scroll by value (maybe the height of the dragged element or less)

pfiaux added a commit to pfiaux/ionic-v1 that referenced this issue Jul 13, 2017
* Stop scrolling when dragged element is moved back into view
* Cap the maximum scrolling speed
see ionic-team#224
pfiaux added a commit to pfiaux/ionic-v1 that referenced this issue Jul 13, 2017
* New drag events where dragged item no longer cause scrolling stop scrolling
* Add a cap on the maximum scroll speed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants