web-dev-qa-db-fra.com

Détection de la direction de PAN dans iOS

Dans mon application, il y a une vue d'image.Im ajoutant PAN geste à cette vue d'image.

Cela fonctionne bien.

La vue de l'image est en mode paysage.

Je souhaite augmenter le nombre d'étiquettes pendant que l'utilisateur effectue un panoramique vers la droite et diminuer ce nombre pendant que l'utilisateur effectue un panoramique vers la gauche.

J'ai beaucoup cherché sur Google, mais je n'ai pas trouvé de solution.

Quelqu'un peut-il m'aider à détecter la direction dans laquelle l'utilisateur effectue un panoramique (gauche/droite)?

38
suji

Dans le sélecteur de cible de votre reconnaissance de gestes, utilisez - (CGPoint)velocityInView:(UIView *)view;:

- (void)panRecognized:(UIPanGestureRecognizer *)rec
{
    CGPoint vel = [rec velocityInView:self.view];
    if (vel.x > 0)
    {
        // user dragged towards the right
        counter++;
    }
    else
    {
        // user dragged towards the left
        counter--;
    }
}

P.s .: Je ne connaissais pas cette méthode avant env. 3 minutes avant. L'un des premiers succès de Google a été la documentation officielle Apple.

89
user529758

Quelque chose comme ça:

- (void)pan:(UIPanGestureRecognizer *)sender
{

    typedef NS_ENUM(NSUInteger, UIPanGestureRecognizerDirection) {
        UIPanGestureRecognizerDirectionUndefined,
        UIPanGestureRecognizerDirectionUp,
        UIPanGestureRecognizerDirectionDown,
        UIPanGestureRecognizerDirectionLeft,
        UIPanGestureRecognizerDirectionRight
    };

    static UIPanGestureRecognizerDirection direction = UIPanGestureRecognizerDirectionUndefined;

    switch (sender.state) {

        case UIGestureRecognizerStateBegan: {

            if (direction == UIPanGestureRecognizerDirectionUndefined) {

                CGPoint velocity = [sender velocityInView:recognizer.view];

                BOOL isVerticalGesture = fabs(velocity.y) > fabs(velocity.x);

                if (isVerticalGesture) {
                    if (velocity.y > 0) {
                        direction = UIPanGestureRecognizerDirectionDown;
                    } else {
                        direction = UIPanGestureRecognizerDirectionUp;
                    }
                }

                else {
                    if (velocity.x > 0) {
                        direction = UIPanGestureRecognizerDirectionRight;
                    } else {
                        direction = UIPanGestureRecognizerDirectionLeft;
                    }
                }
            }

            break;
        }

        case UIGestureRecognizerStateChanged: {
            switch (direction) {
                case UIPanGestureRecognizerDirectionUp: {
                    [self handleUpwardsGesture:sender];
                    break;
                }
                case UIPanGestureRecognizerDirectionDown: {
                    [self handleDownwardsGesture:sender];
                    break;
                }
                case UIPanGestureRecognizerDirectionLeft: {
                    [self handleLeftGesture:sender];
                    break;
                }
                case UIPanGestureRecognizerDirectionRight: {
                    [self handleRightGesture:sender];
                    break;
                }
                default: {
                    break;
                }
            }
        }

        case UIGestureRecognizerStateEnded: {
            direction = UIPanGestureRecognizerDirectionUndefined;   
            break;
        }

        default:
            break;
    }

}

- (void)handleUpwardsGesture:(UIPanGestureRecognizer *)sender
{
    NSLog(@"Up");
}

- (void)handleDownwardsGesture:(UIPanGestureRecognizer *)sender
{
    NSLog(@"Down");
}

- (void)handleLeftGesture:(UIPanGestureRecognizer *)sender
{
    NSLog(@"Left");
}

- (void)handleRightGesture:(UIPanGestureRecognizer *)sender
{
    NSLog(@"Right");
}
36
Adam Waite

Ma réponse précédente dans Swift

public enum Direction: Int {
    case Up
    case Down
    case Left
    case Right

    public var isX: Bool { return self == .Left || self == .Right }
    public var isY: Bool { return !isX }
}

public extension UIPanGestureRecognizer {

    public var direction: Direction? {
        let velocity = velocityInView(view)
        let vertical = fabs(velocity.y) > fabs(velocity.x)
        switch (vertical, velocity.x, velocity.y) {
        case (true, _, let y) where y < 0: return .Up
        case (true, _, let y) where y > 0: return .Down
        case (false, let x, _) where x > 0: return .Right
        case (false, let x, _) where x < 0: return .Left
        default: return nil
        }
    }
}
15
Adam Waite

Voici une version nettoyée Swift 5 version, avec un exemple d'utilisation:

public enum PanDirection: Int {
    case up, down, left, right
    public var isVertical: Bool { return [.up, .down].contains(self) }
    public var isHorizontal: Bool { return !isVertical }
}

public extension UIPanGestureRecognizer {

   var direction: PanDirection? {
        let velocity = self.velocity(in: view)
        let isVertical = abs(velocity.y) > abs(velocity.x)
        switch (isVertical, velocity.x, velocity.y) {
        case (true, _, let y) where y < 0: return .up
        case (true, _, let y) where y > 0: return .down
        case (false, let x, _) where x > 0: return .right
        case (false, let x, _) where x < 0: return .left
        default: return nil
        }
    }

}

@IBAction func pan(_ recognizer: UIPanGestureRecognizer) {        
    if let direction = recognizer.direction {
        if direction.isVertical {
            //do what you want when pan is vertical
        } else if direction == .left {
            //do what you want when pan is left
        }
    }
}
9
Harris

Réécrire la version d'Adam Waite sur Swift 3

public enum PanDirection: Int {
    case up,
    down,
    left,
    right

    public var isX: Bool {
        return self == .left || self == .right
    }

    public var isY: Bool {
        return !isX
    }
}

extension UIPanGestureRecognizer {
    var direction: PanDirection? {
        let velocity = self.velocity(in: view)
        let vertical = fabs(velocity.y) > fabs(velocity.x)
        switch (vertical, velocity.x, velocity.y) {
        case (true, _, let y):
            return y < 0 ? .up : .down

        case (false, let x, _):
            return x > 0 ? .right : .left
        }
    }
}
2
Bohdan Savych

Notez que Adam Swift ci-dessus a une erreur. .Up devrait retourner si y <0 et .down devrait retourner si y> 0 (ils sont inversés).

Donc:

//MARK: - Direction
internal enum Direction {
    case up
    case down
    case left
    case right
}

//MARK: - UIPanGestureRecognizer
internal extension UIPanGestureRecognizer {
    internal var direction: Direction? {
        let velocity = velocityInView(view)
        let isVertical = fabs(velocity.y) > fabs(velocity.x)

        switch (isVertical, velocity.x, velocity.y) {
            case (true, _, let y) where y < 0: return .up
            case (true, _, let y) where y > 0: return .down
            case (false, let x, _) where x > 0: return .right
            case (false, let x, _) where x < 0: return .left
            default: return nil
        }
    }
}
1
Justin Stanley