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 - Community Support Team mankz's Avatar
    Join Date
    Nov 2007
    Location
    Stockholm, Sweden
    Posts
    2,986
    Vote Rating
    169
    mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold mankz is a splendid one to behold

      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
    34
    Steffen Hiller has a spectacular aura about Steffen Hiller has a spectacular aura about

      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
    drb is on a distinguished road

      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
    jvisser is on a distinguished road

      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
    jvisser is on a distinguished road

      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!