Erkennen von Wischen in alle 4 Richtungen


131

Ich muss Swipe verwenden, um die Swipe-Geste nach unten und dann nach rechts zu erkennen. Aber bei schnellem UISwipeGestureRecognizer ist die richtige Richtung vorbestimmt. Und ich weiß nicht, wie ich dies für andere Richtungen verwenden soll.

Antworten:


324

Sie müssen eine UISwipeGestureRecognizerfür jede Richtung haben. Es ist etwas seltsam, weil die UISwipeGestureRecognizer.directionEigenschaft eine Bitmaske im Optionsstil ist, aber jeder Erkenner kann nur eine Richtung verarbeiten. Sie können sie alle an denselben Handler senden, wenn Sie möchten, und sie dort sortieren oder an verschiedene Handler senden. Hier ist eine Implementierung:

override func viewDidLoad() {
    super.viewDidLoad()

    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture))
    swipeRight.direction = .right
    self.view.addGestureRecognizer(swipeRight)

    let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture))
    swipeDown.direction = .down
    self.view.addGestureRecognizer(swipeDown)
}

@objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {

    if let swipeGesture = gesture as? UISwipeGestureRecognizer {

        switch swipeGesture.direction {
        case .right:
            print("Swiped right")
        case .down:
            print("Swiped down")
        case .left:
            print("Swiped left")
        case .up:
            print("Swiped up")
        default:
            break
        }
    }
}

Swift 3:

override func viewDidLoad() {
    super.viewDidLoad()

    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeRight.direction = UISwipeGestureRecognizerDirection.right
    self.view.addGestureRecognizer(swipeRight)

    let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeDown.direction = UISwipeGestureRecognizerDirection.down
    self.view.addGestureRecognizer(swipeDown)
}

func respondToSwipeGesture(gesture: UIGestureRecognizer) {
    if let swipeGesture = gesture as? UISwipeGestureRecognizer {
        switch swipeGesture.direction {
        case UISwipeGestureRecognizerDirection.right:
            print("Swiped right")
        case UISwipeGestureRecognizerDirection.down:
            print("Swiped down")
        case UISwipeGestureRecognizerDirection.left:
            print("Swiped left")
        case UISwipeGestureRecognizerDirection.up:
            print("Swiped up")
        default:
            break
        }
    }
}

"Jeder Erkenner kann nur mit einer Richtung umgehen" - das stimmt nicht. Siehe stackoverflow.com/questions/16184539/…
Sergey Skoblikov

3
"Jeder Erkenner kann nur mit einer Richtung umgehen" - Es ist in Swift wahr und in Objective-C falsch, um genau zu sein.
König-Zauberer

13
Sie müssen nicht UISwipeGestureRecognizerDirectionvor .Downect hinzufügen . Nur verwenden, swipeDown.direction = .Downwenn es ausreicht. Nur ein Tipp =)
Paul Peelen

Können wir dasselbe gestureRecogniser-Objekt zu mehr als einer Ansicht hinzufügen? Ich habe es versucht, aber nicht funktioniert.
Max

3
Wenn Sie @Sergey Skoblikovs Ansatz schnell ausführen (indem Sie dies tun swipe.direction = [.Right,.Down,.Up,.Left]), wird der Erkenner nicht einmal aufgerufen. Vielleicht ist dies ein Problem mit Swift, aber ab sofort funktioniert es nicht.
Knight0fDragon

55

Ich wollte nur dazu beitragen, sieht am Ende eleganter aus:

func addSwipe() {
    let directions: [UISwipeGestureRecognizerDirection] = [.Right, .Left, .Up, .Down]
    for direction in directions {
        let gesture = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipe:"))
        gesture.direction = direction
        self.addGestureRecognizer(gesture)
    }
}

func handleSwipe(sender: UISwipeGestureRecognizer) {
    print(sender.direction)
}

10
self.addGestureRecognizer(gesture)hat einen Fehler für mich verursacht. Was es fixiert war self.view.addGestureRecognizer(gesture);.
ahitt6345

1
@ ahitt6345 Ich habe meinen Code in einer UIViewUnterklasse verwendet, aber Sie haben absolut Recht, wenn Sie in einer sind UIViewController!
Alexandre Cassagne

1
Sauber, beste Antwort für mich.
Christopher Smit

22

Aus dem Storyboard:

  1. Fügen Sie Ihrer Ansicht vier Wischgestenerkenner hinzu.
  2. Legen Sie im Attributinspektor jeweils die Zielrichtung fest. Sie können rechts, links, oben oder unten auswählen
  3. Wählen Sie nacheinander die Wischgestenerkennung aus, steuern Sie + ziehen Sie sie auf Ihren Ansichts-Controller. Geben Sie den Namen ein (sagen wir leftGesture, rightGesture, upGesture und downGesture), ändern Sie die Verbindung in: Action und geben Sie Folgendes ein: UISwipeGestureRecognizer

Aus Ihrer Sicht Controller:

@IBAction func rightGesture(sender: UISwipeGestureRecognizer) {
    print("Right")
}
@IBAction func leftGesture(sender: UISwipeGestureRecognizer) {
    print("Left")
}
@IBAction func upGesture(sender: UISwipeGestureRecognizer) {
    print("Up")
}

@IBAction func downGesture(sender: UISwipeGestureRecognizer) {
    print("Down")
}  

5
Mit dieser Antwort müssen Sie nicht viele Codes schreiben, sondern verwenden das Storyboard und die Verbindungen zwischen dem Storyboard und Ihrem Code. Wenn der Entwickler es vorzieht, auf diese Weise zu arbeiten, ist diese Antwort möglicherweise einfacher. Wenn der Entwickler jedoch lieber mehr in der Codierung arbeitet, ist die erste Antwort definitiv die beste.
user3099333

Ich habe 4 Wischgesten anstelle von einer verwendet und ein Großteil der Arbeitslast befindet sich im Storyboard, anstatt zu codieren.
user3099333

9

Es sieht so aus, als hätten sich die Dinge in letzter Zeit geändert. In XCode 7.2 funktioniert der folgende Ansatz:

override func viewDidLoad() {
    super.viewDidLoad()

    let swipeGesture = UISwipeGestureRecognizer(target: self, action: "handleSwipe:")
    swipeGesture.direction = [.Down, .Up]
    self.view.addGestureRecognizer(swipeGesture)
}

func handleSwipe(sender: UISwipeGestureRecognizer) {
    print(sender.direction)
}

Getestet in Simulator unter iOS 8.4 und 9.2 und auf dem tatsächlichen Gerät unter 9.2.

Oder mit mlcollard ‚s handlicher Erweiterung hier :

let swipeGesture = UISwipeGestureRecognizer() {
    print("Gesture recognized !")
}

swipeGesture.direction = [.Down, .Up]
self.view.addGestureRecognizer(swipeGesture)

5
Der Selektor kann aufgerufen werden, aber die Richtung auf dem Absender ist falsch. Mit anderen Worten, dieser Ansatz ist in Ordnung, wenn Sie die Richtung des Wischens nicht kennen müssen, aber nicht anders.
Robert Gummesson

Funktioniert nicht mehr. In Swift 3 muss der Kontext zum ersten Wert geliefert werden:[UISwipeGestureRecognizerDirection.right, .left, .up, .down]
Brent Faust

7

Apple Swift Version 3.1 - Xcode Version 8.3 (8E162)

Der praktische Weg von Alexandre Cassagnes Ansatz

let directions: [UISwipeGestureRecognizerDirection] = [.up, .down, .right, .left]
for direction in directions {
    let gesture = UISwipeGestureRecognizer(target: self, action: #selector(YourClassName.handleSwipe(gesture:)))
    gesture.direction = direction
    self.view?.addGestureRecognizer(gesture)   
}

func handleSwipe(gesture: UISwipeGestureRecognizer) {
    print(gesture.direction)
    switch gesture.direction {
    case UISwipeGestureRecognizerDirection.down:
        print("down swipe")
    case UISwipeGestureRecognizerDirection.up:
        print("up swipe")
    case UISwipeGestureRecognizerDirection.left:
        print("left swipe")
    case UISwipeGestureRecognizerDirection.right:
        print("right swipe")
    default:
        print("other swipe")
    }
}

1
Bei diesem speziellen Build müssen Sie defaults write com.apple.dt.xcode IDEPlaygroundDisableSimulatorAlternateFramebuffer -bool YESim Terminal ausgeführt werden, um einen Fehler auf einer bestimmten Hardware zu beheben. Es sollte in einer neuen Version von Xcode
Sirens

6

In Swift 4.2 und Xcode 9.4.1

Fügen Sie Ihrer Klasse den Animationsdelegierten CAAnimationDelegate hinzu

//Swipe gesture for left and right
let swipeFromRight = UISwipeGestureRecognizer(target: self, action: #selector(didSwipeLeft))
swipeFromRight.direction = UISwipeGestureRecognizerDirection.left
menuTransparentView.addGestureRecognizer(swipeFromRight)

let swipeFromLeft = UISwipeGestureRecognizer(target: self, action: #selector(didSwipeRight))
swipeFromLeft.direction = UISwipeGestureRecognizerDirection.right
menuTransparentView.addGestureRecognizer(swipeFromLeft)

//Swipe gesture selector function
@objc func didSwipeLeft(gesture: UIGestureRecognizer) {
    //We can add some animation also
    DispatchQueue.main.async(execute: {
            let animation = CATransition()
            animation.type = kCATransitionReveal
            animation.subtype = kCATransitionFromRight
            animation.duration = 0.5
            animation.delegate = self
            animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
            //Add this animation to your view
            self.transparentView.layer.add(animation, forKey: nil)
            self.transparentView.removeFromSuperview()//Remove or hide your view if requirement.
        })
}

//Swipe gesture selector function
@objc func didSwipeRight(gesture: UIGestureRecognizer) {
        // Add animation here
        DispatchQueue.main.async(execute: {
            let animation = CATransition()
            animation.type = kCATransitionReveal
            animation.subtype = kCATransitionFromLeft
            animation.duration = 0.5
            animation.delegate = self
            animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
            //Add this animation to your view
            self.transparentView.layer.add(animation, forKey: nil)
            self.transparentView.removeFromSuperview()//Remove or hide yourview if requirement.
        })
}

Wenn Sie eine Geste aus der Ansicht entfernen möchten, verwenden Sie diesen Code

self.transparentView.removeGestureRecognizer(gesture)

Ex:

func willMoveFromView(view: UIView) {
    if view.gestureRecognizers != nil {
        for gesture in view.gestureRecognizers! {
            //view.removeGestureRecognizer(gesture)//This will remove all gestures including tap etc...
            if let recognizer = gesture as? UISwipeGestureRecognizer {
                //view.removeGestureRecognizer(recognizer)//This will remove all swipe gestures
                if recognizer.direction == .left {//Especially for left swipe
                    view.removeGestureRecognizer(recognizer)
                }
            }
        }
    }
}

Nennen Sie diese Funktion wie

//Remove swipe gesture
self.willMoveFromView(view: self.transparentView)

Auf diese Weise können Sie die verbleibenden Anweisungen schreiben und bitte vorsichtig sein, ob Sie eine Bildlaufansicht von unten nach oben und umgekehrt haben oder nicht

Wenn Sie eine Bildlaufansicht haben, kommt es zu Konflikten zwischen oben und unten und umgekehrt.


4

UISwipeGestureRecognizerhat eine directionEigenschaft mit der folgenden Definition:

var direction: UISwipeGestureRecognizerDirection

Die zulässige Richtung des Wischens für diesen Gestenerkenner.


Das Problem mit Swift 3.0.1 (und darunter) besteht darin, dass das folgende Snippet selbst dann kompiliert wird, wenn es den UISwipeGestureRecognizerDirectionAnforderungen entspricht OptionSet, aber kein positives erwartetes Ergebnis liefert:

// This compiles but does not work
let gesture = UISwipeGestureRecognizer(target: self, action: #selector(gestureHandler))
gesture.direction = [.right, .left, .up, .down]
self.addGestureRecognizer(gesture)

Um dieses Problem zu umgehen, müssen Sie UISwipeGestureRecognizerfür jeden gewünschten eine erstellen direction.


Der folgende Spielplatzcode zeigt, wie Sie mit der Array- Methode mehrere UISwipeGestureRecognizerfür dasselbe UIViewund dasselbe implementieren :selectormap

import UIKit
import PlaygroundSupport

class SwipeableView: UIView {
    convenience init() {
        self.init(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
        backgroundColor = .red

        [UISwipeGestureRecognizerDirection.right, .left, .up, .down].map({
            let gesture = UISwipeGestureRecognizer(target: self, action: #selector(gestureHandler))
            gesture.direction = $0
            self.addGestureRecognizer(gesture)
        })
    }

    func gestureHandler(sender: UISwipeGestureRecognizer) {
        switch sender.direction {
        case [.left]:   frame.origin.x -= 10
        case [.right]:  frame.origin.x += 10
        case [.up]:     frame.origin.y -= 10
        case [.down]:   frame.origin.y += 10
        default:        break
        }
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view.addSubview(SwipeableView())
    }
}

let controller = ViewController()
PlaygroundPage.current.liveView = controller

das gleiche Problem noch in xcode 8.3 - kompiliert, aber nicht funktioniert - ich habe nur für links und rechts dieses zurückUISwipeGestureRecognizerDirection(rawValue: 15)
John

4

Wischen Sie mit der Geste zur gewünschten Ansicht oder zur Ansicht des Controllers in Swift 5 & XCode 11 basierend auf @Alexandre Cassagne

override func viewDidLoad() {
    super.viewDidLoad()

    addSwipe()
}

func addSwipe() {
    let directions: [UISwipeGestureRecognizer.Direction] = [.right, .left, .up, .down]
    for direction in directions {
        let gesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe))
        gesture.direction = direction
        self.myView.addGestureRecognizer(gesture)// self.view
    }
}

@objc func handleSwipe(sender: UISwipeGestureRecognizer) {
    let direction = sender.direction
    switch direction {
        case .right:
            print("Gesture direction: Right")
        case .left:
            print("Gesture direction: Left")
        case .up:
            print("Gesture direction: Up")
        case .down:
            print("Gesture direction: Down")
        default:
            print("Unrecognized Gesture Direction")
    }
}

3

Wischgeste in Swift 5

  override func viewDidLoad() {
    super.viewDidLoad()
    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
    swipeLeft.direction = .left
    self.view!.addGestureRecognizer(swipeLeft)

    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
    swipeRight.direction = .right
    self.view!.addGestureRecognizer(swipeRight)

    let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
    swipeUp.direction = .up
    self.view!.addGestureRecognizer(swipeUp)

    let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
    swipeDown.direction = .down
    self.view!.addGestureRecognizer(swipeDown)
}

@objc func handleGesture(gesture: UISwipeGestureRecognizer) -> Void {
    if gesture.direction == UISwipeGestureRecognizer.Direction.right {
        print("Swipe Right")
    }
    else if gesture.direction == UISwipeGestureRecognizer.Direction.left {
        print("Swipe Left")
    }
    else if gesture.direction == UISwipeGestureRecognizer.Direction.up {
        print("Swipe Up")
    }
    else if gesture.direction == UISwipeGestureRecognizer.Direction.down {
        print("Swipe Down")
    }
}

2

Erstellen Sie zuerst einen baseViewControllerund fügen Sie viewDidLoaddiesen Code "swift4" hinzu:

class BaseViewController: UIViewController {             

     override func viewDidLoad() {
         super.viewDidLoad()
         let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(swiped))
         swipeRight.direction = UISwipeGestureRecognizerDirection.right
         self.view.addGestureRecognizer(swipeRight)
         let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(swiped))
         swipeLeft.direction = UISwipeGestureRecognizerDirection.left
         self.view.addGestureRecognizer(swipeLeft)
     }

     // Example Tabbar 5 pages
     @objc func swiped(_ gesture: UISwipeGestureRecognizer) {
         if gesture.direction == .left {
            if (self.tabBarController?.selectedIndex)! < 5 {
                self.tabBarController?.selectedIndex += 1
            }
         } else if gesture.direction == .right {
             if (self.tabBarController?.selectedIndex)! > 0 {
                 self.tabBarController?.selectedIndex -= 1
             }
         }
     }  
}

Und benutze diese baseControllerKlasse:

class YourViewController: BaseViewController {
    // its done. Swipe successful
    //Now you can use all the Controller you have created without writing any code.    
}

1

Nur eine coolere, schnelle Syntax für Nates Antwort:

[UISwipeGestureRecognizerDirection.right,
 UISwipeGestureRecognizerDirection.left,
 UISwipeGestureRecognizerDirection.up,
 UISwipeGestureRecognizerDirection.down].forEach({ direction in
    let swipe = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipe.direction = direction
    self.view.addGestureRecognizer(swipe)
 })

1

Einfach. Folgen Sie einfach dem Code unten und genießen Sie.

//SwipeGestureMethodUsing
func SwipeGestureMethodUsing ()
{
    //AddSwipeGesture
    [UISwipeGestureRecognizerDirection.right,
     UISwipeGestureRecognizerDirection.left,
     UISwipeGestureRecognizerDirection.up,
     UISwipeGestureRecognizerDirection.down].forEach({ direction in
        let swipe = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
        swipe.direction = direction
        window?.addGestureRecognizer(swipe)
     })
}

//respondToSwipeGesture
func respondToSwipeGesture(gesture: UIGestureRecognizer) {

    if let swipeGesture = gesture as? UISwipeGestureRecognizer
    {
        switch swipeGesture.direction
        {
        case UISwipeGestureRecognizerDirection.right:
            print("Swiped right")
        case UISwipeGestureRecognizerDirection.down:
            print("Swiped down")
        case UISwipeGestureRecognizerDirection.left:
            print("Swiped left")
        case UISwipeGestureRecognizerDirection.up:
            print("Swiped up")
        default:
            break
        }
    }
}

1

Für Swift 5 ist es aktualisiert

//Add in ViewDidLoad
let gesture = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.handleSwipe))
        gesture.direction = .right
        self.view.addGestureRecognizer(gesture)

//Add New Method
@objc func handleSwipe(sender: UISwipeGestureRecognizer) {
        print("swipe direction is",sender.direction)

    }

Wie ist dies eine Antwort auf die Frage des OP? Das Problem bestand darin, einen eleganten Weg zu finden, um dem Wischgestenerkenner mehrere Richtungen hinzuzufügen.
Shashwat

1

Nach einer Weile herumgraben:

Der kürzeste Weg , um Wischbewegungen für alle 4 Richtungen hinzuzufügen, ist:

override func viewDidLoad() {
    super.viewDidLoad()    
    for direction in [UISwipeGestureRecognizer.Direction.down, .up, .left, .right]{
        let swipeGest = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(_:)))
        swipeGest.direction = direction
        self.view.addGestureRecognizer(swipeGest)
    }
} 

@objc func swipeAction(_ gesture: UISwipeGestureRecognizer){
    switch gesture.direction {
    case UISwipeGestureRecognizer.Direction.right:
        print("Swiped right")
    case UISwipeGestureRecognizer.Direction.down:
        print("Swiped down")
    case UISwipeGestureRecognizer.Direction.left:
        print("Swiped left")
    case UISwipeGestureRecognizer.Direction.up:
        print("Swiped up")
    default: break
}

1

In Swift 5,

let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe))
swipeGesture.direction = [.left, .right, .up, .down]
view.addGestureRecognizer(swipeGesture)

0

Dies kann durch einfaches Deklarieren einer Funktion erfolgen, die alle Ihre UISwipeGestureRecognizer-Swipe-Anweisungen verarbeitet. Hier ist mein Code:

let swipeGestureRight = UISwipeGestureRecognizer(target: self, action:#selector(ViewController.respondToSwipeGesture(_:)) )
swipeGestureRight.direction = UISwipeGestureRecognizerDirection.right
self.view .addGestureRecognizer(swipeGestureRight)

let swipeGestureLeft = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
swipeGestureLeft.direction = UISwipeGestureRecognizerDirection.left
self.view.addGestureRecognizer(swipeGestureLeft)

let swipeGestureUp = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
swipeGestureUp.direction = UISwipeGestureRecognizerDirection.up
self.view.addGestureRecognizer(swipeGestureUp)

let swipeGestureDown = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
swipeGestureDown.direction = UISwipeGestureRecognizerDirection.down
self.view.addGestureRecognizer(swipeGestureDown)

Hier ist die Funktion, die die Swipedirection-Funktionalität steuert:

func respondToSwipeGesture(_ sender: UIGestureRecognizer) {
    if let swipeGesture = sender as? UISwipeGestureRecognizer {
        switch swipeGesture.direction {
            case UISwipeGestureRecognizerDirection.right:
                print("right swipe")
            case UISwipeGestureRecognizerDirection.left:
                print("leftSwipe")
            case UISwipeGestureRecognizerDirection.up:
                print("upSwipe")
            case UISwipeGestureRecognizerDirection.down:
                print("downSwipe")
            default:
                break
        }
    }
}

0

Einfach so: ( Swift 4.2.1 )

UISwipeGestureRecognizer.Direction.init(
  rawValue: UISwipeGestureRecognizer.Direction.left.rawValue |
            UISwipeGestureRecognizer.Direction.right.rawValue |
            UISwipeGestureRecognizer.Direction.up.rawValue |
            UISwipeGestureRecognizer.Direction.down.rawValue
)

2
Fügen Sie Ihrem Code eine Beschreibung hinzu, damit er besser wird.
Poul Bak
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.