Page 2 of 2 FirstFirst 12
Results 11 to 15 of 15

Thread: Finger move tolerance when tapping

    You found a bug! We've classified it as TOUCH-3696 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #11
    Sencha Premium User mankz's Avatar
    Join Date
    Nov 2007
    Location
    Stockholm, Sweden
    Posts
    3,078
    Vote Rating
    184
      0  

    Default

    Better to use a tolerance value, this is how we solve this issue in our Touch Scheduler:
    Code:
    /**
     * A event recogniser which knows when you tap and hold for more than {@link #minDuration} ms (defaults to 400ms).
     *
     * @private
     */
    Ext.define('Sch.recognizer.SemiLongPress', {
        extend: 'Ext.event.recognizer.SingleTouch',
    
        /**
         * @cfg {Int} moveTolerance
         * While pressing a finger on the screen, it can be hard to keep it perfectly still - which aborts a normal 'longpress' gesture.
         * Setting this tolerance value allows for some slight movement during the press.
         */
        moveTolerance : 5,
    
        inheritableStatics: {
            DURATION_NOT_ENOUGH: 0x20
        },
    
        config: {
            minDuration: 400
        },
    
        handledEvents: ['semilongpress'],
    
        /**
         * @event semilongpress
         * Fires when you touch and hold finger (almost) still for more than 400 ms.
         * @param {Ext.event.Event} event The {@link Ext.event.Event} event encapsulating the DOM event.
         * @param {HTMLElement} node The target of the event.
         * @param {Object} options The options object passed to Ext.mixin.Observable.addListener.
         */
        fireLongPress: function(e) {
            var touch = e.changedTouches[0];
            
            this.fire('semilongpress', e, [touch], {
                touch: touch,
                duration: this.getMinDuration()
            });
    
            this.isLongPress = true;
        },
    
        onTouchStart: function(e) {
            var me = this;
    
            if (this.callParent(arguments) === false) {
                return false;
            }
    
            this.isLongPress = false;
            this._touchX = e.touch.pageX;
            this._touchY = e.touch.pageY;
    
            this.timer = setTimeout(function() {
                me.fireLongPress(e);
            }, this.getMinDuration());
        },
    
        onTouchMove: function(e) {
            if (Math.abs(this._touchX - e.touch.pageX) > this.moveTolerance ||
                Math.abs(this._touchY - e.touch.pageY) > this.moveTolerance) {
                return this.fail(this.self.TOUCH_MOVED);
            }
        },
    
        onTouchEnd: function() {
            if (!this.isLongPress) {
                return this.fail(this.self.DURATION_NOT_ENOUGH);
            }
        },
    
        fail: function() {
            clearTimeout(this.timer);
    
            return this.callParent(arguments);
        }
    
    });

  2. #12
    Ext JS Premium Member Steffen Hiller's Avatar
    Join Date
    Mar 2008
    Posts
    786
    Vote Rating
    36
      0  

    Default

    Thanks for all the work around suggestions!

    Sencha seems to solve this problem very elegantly in ST 2.2.0.alpha.

    Here's the code as override that also works for ST 2.1. (I only changed the moveDistance var to be hard coded instead of a config var since configs don't work in overrides.)

    Code:
    Ext.define('App.override.event.recognizer.Tap', {
        override: 'Ext.event.recognizer.Tap',
    
        handledEvents: ['tap', 'tapcancel'],
    
        onTouchStart: function(e) {
            if (this.callSuper(arguments) === false) {
                return false;
            }
    
            this.startPoint = e.changedTouches[0].point;
        },
    
        onTouchMove: function(e) {
            var touch = e.changedTouches[0],
                point = touch.point,
                moveDistance = 20;
    
            if (Math.abs(point.getDistanceTo(this.startPoint)) >= moveDistance) {
                this.fire('tapcancel', e, [touch], {
                    touch: touch
                });
                return this.fail(this.self.TOUCH_MOVED);
            }
        },
    
        onTouchEnd: function(e) {
            var touch = e.changedTouches[0];
    
            this.fire('tap', e, [touch], {
                touch: touch
            });
        }
    });

  3. #13
    Sencha User
    Join Date
    Sep 2011
    Location
    Boston
    Posts
    149
    Vote Rating
    7
      0  

    Default LongPress too

    Here is what we are using as of 2.2.1. It seems to work.
    Code:
            // Adds a little damping so that small touch moves do not prevent taphold and itemtaphold
            Ext.define('Ext.overrides.event.recognizer.LongPress', {
                override: 'Ext.event.recognizer.LongPress',
                onTouchStart: function (e) {
                    this.startPoint = e.changedTouches[0].point;
                    if (this.callParent(arguments) === false) {
                        return false;
                    }
                },
                onTouchMove: function (e) {
                    var touch = e.changedTouches[0],
                        point = touch.point
                        moveDistance = 7;
                    if (Math.abs(point.getDistanceTo(this.startPoint)) >= moveDistance) {
                        return this.fail(this.self.TOUCH_MOVED);
                    }
                }
            });

  4. #14
    Sencha User
    Join Date
    Apr 2012
    Location
    Netherlands
    Posts
    30
    Vote Rating
    1
      0  

    Default Does not work reliably on iPad

    I still have the same problem with Sencha Touch 2.4.2 on an iPad with iOS 8.4.1

    I will try if any of the workarounds posted here will fix the issues.

  5. #15
    Sencha User
    Join Date
    Apr 2012
    Location
    Netherlands
    Posts
    30
    Vote Rating
    1
      0  

    Default

    Sencha Touch 2.4.2 still needs the workaround for the iPad. Take care though: the code posted above is missing a comma after 'point = touch.point'. Add it otherwise you might be leaking moveDistance as a global variable!

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •