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)?
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.
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");
}
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
}
}
}
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
}
}
}
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
}
}
}
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
}
}
}