Cách nhận biết vuốt theo cả 4 hướng


131

Tôi cần sử dụng thao tác vuốt để nhận ra cử chỉ vuốt xuống và sau đó phải. Nhưng trên UISwipeGestureRecognizer nhanh chóng đã định trước đúng hướng .. Và tôi không biết làm thế nào để sử dụng các hướng này ..

Câu trả lời:


324

Bạn cần phải có một UISwipeGestureRecognizercho mỗi hướng. Điều này hơi lạ vì thuộc UISwipeGestureRecognizer.directiontính là mặt nạ bit kiểu tùy chọn, nhưng mỗi bộ nhận dạng chỉ có thể xử lý một hướng. Bạn có thể gửi tất cả chúng cho cùng một trình xử lý nếu bạn muốn, và sắp xếp nó ra khỏi đó, hoặc gửi chúng cho các trình xử lý khác nhau. Đây là một triển khai:

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

"Mỗi bộ nhận dạng chỉ có thể xử lý một hướng" - điều đó không đúng. Xem stackoverflow.com/questions/16184539/ Mạnh
Serge Skoblikov

3
"Mỗi bộ nhận dạng chỉ có thể xử lý một hướng" - Đó là sự thật trong Swift và sai trong Objective-C là cụ thể.
King-Wizard

13
Bạn không phải thêm UISwipeGestureRecognizerDirectionvào trước .Downect. Chỉ cần sử dụng swipeDown.direction = .Downnếu đủ. Chỉ là một mẹo =)
Paul Peelen

chúng ta có thể thêm cùng một đối tượng cử chỉ nhận thức vào nhiều chế độ xem không? Tôi đã thử nhưng không hoạt động.
Tối đa

3
nếu bạn thực hiện phương pháp nhanh chóng của @Sergey Skoblikovs, (bằng cách thực hiện swipe.direction = [.Right,.Down,.Up,.Left]), trình nhận dạng thậm chí sẽ không được gọi, có lẽ đây là một vấn đề với swift, nhưng ngay bây giờ không hoạt động.
Knight0fDragon

55

Tôi chỉ cảm thấy như đóng góp điều này, cuối cùng trông thanh lịch hơn:

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)gây ra một lỗi cho tôi Những gì đã cố định nó là self.view.addGestureRecognizer(gesture);.
ahitt6345

1
@ ahitt6345 Tôi đã sử dụng mã của mình trong một UIViewlớp con, nhưng bạn hoàn toàn đúng nếu bạn ở trong một UIViewController!
Alexandre Cassagne

1
Sạch sẽ, câu trả lời tốt nhất cho tôi.
Christopher Smit

22

Từ bảng phân cảnh:

  1. Thêm bốn nhận dạng cử chỉ vuốt vào xem của bạn.
  2. Đặt từng cái với hướng đích từ thanh tra thuộc tính. Bạn có thể chọn phải, trái, lên hoặc xuống
  3. Từng người một, chọn trình nhận dạng cử chỉ vuốt, điều khiển + kéo đến trình điều khiển xem của bạn. Chèn tên (hãy để chúng tôi nói leftGesture, rightGesture, upGesture và downGesture), thay đổi kết nối thành: Action và gõ thành: UISwipeGestureRecognizer

Từ viewControll của bạn:

@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
Với câu trả lời này, bạn không cần phải viết nhiều mã nhưng bạn sử dụng bảng phân cảnh và các kết nối giữa bảng phân cảnh và mã của bạn. Trong trường hợp nhà phát triển thích làm việc theo cách này, câu trả lời này có thể dễ dàng hơn nhưng nếu nhà phát triển thích làm việc nhiều hơn với mã hóa, chắc chắn câu trả lời đầu tiên là tốt nhất.
dùng3099333

Tôi đã sử dụng 4 cử chỉ vuốt thay vì một và rất nhiều khối lượng công việc có trong bảng phân cảnh thay vì mã hóa.
dùng3099333

9

Có vẻ như mọi thứ đã thay đổi gần đây. Trong XCode 7.2, cách tiếp cận sau hoạt động:

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

Đã thử nghiệm trong Trình mô phỏng trên iOS 8.4 và 9.2 và trên thiết bị thực tế vào ngày 9.2.

Hoặc, sử dụng tiện ích mở rộng tiện dụng của mlcollard tại đây :

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

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

5
Bộ chọn có thể được gọi nhưng hướng trên người gửi không chính xác. Nói cách khác, cách tiếp cận này là tốt nếu bạn không cần biết hướng vuốt nhưng không thì khác.
Robert Gummesson

Công việc ngắn hạn. Trong Swift 3, bối cảnh phải được cung cấp cho giá trị đầu tiên:[UISwipeGestureRecognizerDirection.right, .left, .up, .down]
Brent Faust

7

Apple Swift phiên bản 3.1 - Xcode Phiên bản 8.3 (8E162)

Cách tiện dụng từ cách tiếp cận của 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
Với bản dựng cụ thể này, bạn cần chạy defaults write com.apple.dt.xcode IDEPlaygroundDisableSimulatorAlternateFramebuffer -bool YEStrong Terminal để sửa lỗi trên một số phần cứng. Nó nên được sửa trong một phiên bản Xcode mới
Sirens

6

Trong Swift 4.2 và Xcode 9.4.1

Thêm đại biểu Hoạt hình, CAAnimationDelegate vào lớp của bạn

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

Nếu bạn muốn xóa cử chỉ khỏi chế độ xem, hãy sử dụng mã này

self.transparentView.removeGestureRecognizer(gesture)

Ví dụ:

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

Gọi hàm này như

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

Như thế này, bạn có thể viết các hướng còn lại và vui lòng cẩn thận xem bạn có xem cuộn hay không từ dưới lên trên và ngược lại

Nếu bạn có chế độ xem cuộn, bạn sẽ nhận được xung đột từ trên xuống dưới và xem các cử chỉ ngược lại.


4

UISwipeGestureRecognizercó một directiontài sản có định nghĩa sau:

var direction: UISwipeGestureRecognizerDirection

Hướng cho phép của thao tác vuốt cho nhận dạng cử chỉ này.


Vấn đề với Swift 3.0.1 (và bên dưới) là ngay cả khi UISwipeGestureRecognizerDirectiontuân thủ OptionSet, đoạn mã sau sẽ biên dịch nhưng sẽ không tạo ra bất kỳ kết quả mong đợi tích cực nào:

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

Như một cách giải quyết, bạn sẽ phải tạo một UISwipeGestureRecognizercho mỗi mong muốn direction.


Mã Playground sau đây cho thấy cách triển khai một số UISwipeGestureRecognizercho cùng UIViewvà giống nhau selectorbằng mapphương thức của 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

vấn đề tương tự vẫn xảy ra ở xcode 8.3 - được biên dịch nhưng không hoạt động - Tôi chỉ quay lại bên trái và bên phải nàyUISwipeGestureRecognizerDirection(rawValue: 15)
John

4

Vuốt cử chỉ đến chế độ xem bạn muốn hoặc toàn bộ chế độ xem toàn bộ điều khiển trong Swift 5 & XCode 11 dựa trên @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

Cử chỉ vuốt trong 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

Đầu tiên tạo một baseViewControllervà thêm viewDidLoadmã này "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
             }
         }
     }  
}

Và sử dụng baseControllerlớp này :

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

1

Chỉ cần một cú pháp nhanh hơn cho câu trả lời của 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

Dễ dàng. Chỉ cần làm theo mã dưới đây và thưởng thức.

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

Đối với Swift 5, nó được cập nhật

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

    }

Làm thế nào đây là một câu trả lời cho câu hỏi của OP? Vấn đề là tìm ra một cách thanh lịch để thêm nhiều hướng vào trình nhận dạng cử chỉ vuốt.
shashwat

1

Sau khi đào xung quanh một lúc:

Cách ngắn nhất để thêm thao tác vuốt cho cả 4 hướng là:

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

Trong Swift 5,

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

0

Nó có thể được thực hiện bằng cách chỉ cần khai báo một chức năng sẽ xử lý tất cả các hướng vuốt UISwipeGestureRecognizer của bạn. Đây là mã của tôi:

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)

Đây là chức năng sẽ xử lý chức năng 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

Cứ như thế: ( 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
Thêm một số mô tả vào mã của bạn, xin vui lòng sẽ làm cho nó tốt hơn.
Poul Bak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.