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
    Helsingborg, Sweden
    Posts
    2,455
    Vote Rating
    51
    mankz is a jewel in the rough mankz is a jewel in the rough mankz is a jewel in the rough mankz is a jewel in the rough

      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
    753
    Vote Rating
    20
    Steffen Hiller will become famous soon enough

      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
            });
        }
    });