Bagaimana mengenali gesek di semua 4 arah


131

Saya perlu menggunakan swipe untuk mengenali gerakan swipe ke bawah lalu ke kanan. Tetapi dengan cepat UISwipeGestureRecognizer telah ditentukan sebelumnya Arah yang benar .. Dan saya tidak tahu bagaimana membuatnya untuk menggunakan petunjuk lain ..

Jawaban:


324

Anda harus memiliki satu UISwipeGestureRecognizeruntuk setiap arah. Agak aneh karena UISwipeGestureRecognizer.directionproperti ini adalah topeng bit gaya-opsi, tetapi setiap pengenal hanya dapat menangani satu arah. Anda dapat mengirim semuanya ke penangan yang sama jika diinginkan, dan mengatasinya di sana, atau mengirimnya ke penangan yang berbeda. Inilah satu implementasi:

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

"setiap pengenal hanya dapat menangani satu arah" - itu tidak benar. Lihat stackoverflow.com/questions/16184539/...
Sergey Skoblikov

3
"setiap pengenal hanya dapat menangani satu arah" - Ini benar dalam Swift dan false di Objective-C untuk lebih spesifik.
King-Wizard

13
Anda tidak perlu menambahkan UISwipeGestureRecognizerDirectiondi depan .Downdll. Hanya menggunakan swipeDown.direction = .Downjika cukup. Hanya sebuah tip =)
Paul Peelen

dapatkah kita menambahkan objek gestureRecogniser yang sama ke lebih dari satu tampilan? Saya sudah mencoba tetapi tidak berhasil.
Maks.

3
jika Anda melakukan pendekatan @Sergey Skoblikovs di swift, (dengan melakukan swipe.direction = [.Right,.Down,.Up,.Left] ), pengenal bahkan tidak akan dipanggil, mungkin ini adalah masalah dengan swift, tetapi pada saat ini tidak berfungsi.
Knight0fDragon

55

Saya hanya merasa ingin berkontribusi ini, pada akhirnya terlihat lebih elegan:

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)menyebabkan kesalahan bagi saya. Apa yang diperbaiki itu self.view.addGestureRecognizer(gesture);.
ahitt6345

1
@ ahitt6345 Saya menggunakan kode saya di UIViewsubkelas, tetapi Anda benar jika Anda berada di UIViewController!
Alexandre Cassagne

1
Bersih, jawaban terbaik untukku.
Christopher Smit

22

Dari storyboard:

  1. Tambahkan empat pengenal isyarat gesek ke tampilan Anda.
  2. Atur masing-masing dengan arah target dari inspektur atribut. Anda dapat memilih kanan, kiri, atas atau bawah
  3. Satu per satu, pilih pengukur gerakan usap, kontrol + seret ke pengontrol tampilan Anda. Masukkan nama (katakanlah leftGesture, rightGesture, upGesture dan downGesture), ubah koneksi ke: Action dan ketik ke: UISwipeGestureRecognizer

Dari viewController Anda:

@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
Dengan jawaban ini Anda tidak perlu menulis banyak kode tetapi Anda menggunakan storyboard dan koneksi antara storyboard dan kode Anda. Jika pengembang lebih suka bekerja dengan cara ini, jawaban ini mungkin lebih mudah tetapi jika pengembang lebih suka bekerja lebih dalam pengkodean, pasti jawaban pertama adalah yang terbaik.
user3099333

Saya menggunakan 4 gerakan menggesek bukannya satu dan banyak beban pekerjaan di storyboard bukan coding.
user3099333

9

Sepertinya hal-hal telah berubah belakangan ini. Dalam XCode 7.2 pendekatan berikut ini berfungsi:

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

Diuji dalam Simulator pada iOS 8.4 dan 9.2 dan pada perangkat aktual pada 9.2.

Atau, menggunakan ekstensi praktis mlcollard di sini :

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

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

5
Pemilih mungkin dipanggil tetapi arah pada pengirim tidak benar. Dengan kata lain, pendekatan ini baik-baik saja jika Anda tidak perlu tahu arah gesek tetapi tidak sebaliknya.
Robert Gummesson

Tidak lagi berfungsi. Dalam Swift 3, konteksnya harus diberikan ke nilai pertama:[UISwipeGestureRecognizerDirection.right, .left, .up, .down]
Brent Faust

7

Apple Swift versi 3.1 - Xcode Versi 8.3 (8E162)

Cara praktis dari pendekatan Alexandre Cassagne

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
Dengan build khusus ini Anda perlu menjalankan defaults write com.apple.dt.xcode IDEPlaygroundDisableSimulatorAlternateFramebuffer -bool YESTerminal untuk memperbaiki bug pada beberapa perangkat keras. Itu harus diperbaiki dalam versi baru Xcode
Sirens

6

Dalam Swift 4.2 dan Xcode 9.4.1

Tambahkan delegasi Animasi, CAAnimationDelegate ke kelas Anda

//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.
        })
}

Jika Anda ingin menghapus gesture dari tampilan, gunakan kode ini

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

Sebut fungsi ini seperti

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

Seperti ini, Anda dapat menulis arahan yang tersisa dan harap berhati-hati apakah Anda memiliki tampilan gulir atau tidak dari bawah ke atas dan sebaliknya

Jika Anda memiliki tampilan gulir, Anda akan mendapatkan konflik untuk Atas ke bawah dan melihat gerakan sebaliknya.


4

UISwipeGestureRecognizermemiliki directionproperti yang memiliki definisi berikut:

var direction: UISwipeGestureRecognizerDirection

Arah gesek yang diizinkan untuk pengenal isyarat ini.


Masalah dengan Swift 3.0.1 (dan di bawah) adalah bahwa meskipun UISwipeGestureRecognizerDirectionsesuai OptionSet, cuplikan berikut akan dikompilasi tetapi tidak akan menghasilkan hasil yang diharapkan positif:

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

Sebagai solusinya, Anda harus membuat UISwipeGestureRecognizeruntuk setiap yang diinginkan direction.


Kode Playground berikut menunjukkan cara menerapkan beberapa UISwipeGestureRecognizeruntuk yang sama UIViewdan yang sama selectormenggunakan mapmetode Array :

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

masalah yang sama masih di xcode 8.3 - dikompilasi tetapi tidak berfungsi - Saya mendapatkan hanya untuk kiri dan kanan ini kembaliUISwipeGestureRecognizerDirection(rawValue: 15)
John

4

Geser isyarat ke tampilan yang Anda inginkan, atau seluruh tampilan viewcontroller di Swift 5 & XCode 11 berdasarkan @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

Geser Gerakan di 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

Pertama buat a baseViewControllerdan tambahkan viewDidLoadkode ini "swift4":

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

Dan gunakan baseControllerkelas ini :

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

2

Dalam Swift 5,

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

1

Hanya sintaks cepat swift untuk jawaban Nate:

[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

Mudah. Ikuti saja kode di bawah ini dan selamat menikmati.

//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

Untuk Swift 5 diperbarui

//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)

    }

Bagaimana ini merupakan jawaban untuk pertanyaan OP? Masalahnya adalah menemukan cara yang elegan untuk menambahkan banyak arah ke pengenal isyarat gesek.
shashwat

1

Setelah menggali sebentar:

Cara terpendek untuk menambahkan gesekan untuk semua 4 arah adalah:

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
}

0

Ini dapat dilakukan dengan hanya mendeklarasikan satu fungsi yang akan menangani semua usapan UISwipeGestureRecognizer swipe Anda. Ini kode saya:

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)

Berikut adalah fungsi yang akan memberikan fungsi swipedirection:

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

Persis seperti itu: ( 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
Tambahkan beberapa deskripsi ke kode Anda, tolong itu akan membuatnya lebih baik.
Poul Bak
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.