Как распознать салфетки во всех 4 направлениях


131

Мне нужно использовать смахивание, чтобы распознать жест смахивания вниз, а затем вправо. Но на быстром UISwipeGestureRecognizer есть предопределенное правильное направление .. И я не знаю, как это сделать для использования других направлений ..

Ответы:


324

Вам необходимо иметь по одному UISwipeGestureRecognizerна каждое направление. Это немного странно, потому что UISwipeGestureRecognizer.directionсвойство представляет собой битовую маску в стиле параметров, но каждый распознаватель может обрабатывать только одно направление. Вы можете отправить их все одному обработчику, если хотите, и отсортировать их там, или отправить их разным обработчикам. Вот одна реализация:

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

Свифт 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
        }
    }
}

«каждый распознаватель может обрабатывать только одно направление» - это неправда. См. Stackoverflow.com/questions/16184539/…
Сергей Скобликов

3
«Каждый распознаватель может обрабатывать только одно направление» - это верно в Swift и неверно в Objective-C, если быть точным.
King-Wizard

13
Вам не нужно добавлять UISwipeGestureRecognizerDirectionперед .Downect. Просто использую, swipeDown.direction = .Downесли достаточно. Просто совет =)
Пол Пилен

можем ли мы добавить один и тот же объект gestureRecogniser в несколько представлений? Я пробовал, но не работал.
Макс,

3
если вы выполните подход @Sergey Skoblikovs быстро, (путем выполнения swipe.direction = [.Right,.Down,.Up,.Left]), распознаватель даже не будет вызван, возможно, это проблема с swift, но на данный момент не работает.
Knight0fDragon

55

Мне просто захотелось внести свой вклад, в итоге выглядит более элегантно:

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)вызвал для меня ошибку. Что исправлено было self.view.addGestureRecognizer(gesture);.
ahitt6345 05

1
@ ahitt6345 Я использовал свой код в UIViewподклассе, но вы абсолютно правы, если используете UIViewController!
Александр Кассань

1
Чистый, лучший ответ для меня.
Кристофер Смит,

22

Из раскадровки:

  1. Добавьте на вид четыре средства распознавания жестов смахивания.
  2. Задайте каждому из них целевое направление из инспектора атрибутов. Вы можете выбрать вправо, влево, вверх или вниз
  3. Один за другим выберите распознаватель жестов смахивания, нажмите Ctrl + перетащите на контроллер просмотра. Вставьте имя (скажем, leftGesture, rightGesture, upGesture и downGesture), измените соединение на: Action и введите: UISwipeGestureRecognizer

Из вашего viewController:

@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
По этому ответу вам не нужно писать много кода, но вы используете раскадровку и связи между раскадровкой и вашим кодом. В случае, если разработчик предпочитает работать таким образом, этот ответ может быть проще, но если разработчик предпочитает больше работать над кодированием, определенно первый ответ будет лучшим.
user3099333

Я использовал 4 жеста смахивания вместо одного, и большая часть рабочей нагрузки приходится на раскадровку, а не на кодирование.
user3099333

9

Похоже, что за последнее время все изменилось. В XCode 7.2 работает следующий подход:

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

Протестировано в Simulator на iOS 8.4 и 9.2 и на реальном устройстве на 9.2.

Или, используя удобное расширение mlcollard здесь :

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

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

5
Селектор может быть вызван, но направление отправителя неверное. Другими словами, этот подход хорош, если вам не нужно знать направление смахивания, но не иначе.
Роберт Гуммессон

Больше не работает. В Swift 3 контекст должен быть [UISwipeGestureRecognizerDirection.right, .left, .up, .down]
Brent Faust

7

Apple Swift версии 3.1 - Xcode версии 8.3 (8E162)

Удобный способ из подхода Александра Кассаня

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
С этой конкретной сборкой вам нужно запустить defaults write com.apple.dt.xcode IDEPlaygroundDisableSimulatorAlternateFramebuffer -bool YESв Терминале, чтобы исправить ошибку на некотором оборудовании. Это должно быть исправлено в новой версии Xcode
Sirens

6

В Swift 4.2 и Xcode 9.4.1

Добавьте делегата анимации CAAnimationDelegate в свой класс

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

Если вы хотите удалить жест из представления, используйте этот код

self.transparentView.removeGestureRecognizer(gesture)

Пример:

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

Вызовите эту функцию как

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

Таким образом вы можете написать оставшиеся направления и, пожалуйста, будьте осторожны, есть ли у вас режим прокрутки или нет снизу вверх и наоборот.

Если у вас есть режим прокрутки, вы получите конфликт при просмотре сверху вниз и обратных жестах.


4

UISwipeGestureRecognizerимеет directionсвойство, имеющее следующее определение:

var direction: UISwipeGestureRecognizerDirection

Допустимое направление смахивания для этого распознавателя жестов.


Проблема со Swift 3.0.1 (и ниже) заключается в том, что даже если он UISwipeGestureRecognizerDirectionсоответствует OptionSet, следующий фрагмент будет компилироваться, но не даст положительного ожидаемого результата:

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

В качестве обходного пути вам нужно будет создать UISwipeGestureRecognizerдля каждого желаемого direction.


Следующий код игровой площадки показывает, как реализовать несколько UISwipeGestureRecognizerодинаковых UIViewи одинаковых selectorс помощью mapметода 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

та же проблема все еще в xcode 8.3 - скомпилирована, но не работает - я получил только левую и правую эту спинуUISwipeGestureRecognizerDirection(rawValue: 15)
Джон

4

Проведите жестом по экрану, который вы хотите, или viewcontroller полностью в Swift 5 и XCode 11 на основе @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

Жест смахивания в 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

Сначала создайте baseViewControllerи добавьте viewDidLoadэтот код "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
             }
         }
     }  
}

И используйте этот baseControllerкласс:

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

2

В Swift 5

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

1

Просто более крутой быстрый синтаксис для ответа Нейта:

[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

Легко. Просто следуйте приведенному ниже коду и наслаждайтесь.

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

Покопавшись немного:

Самый короткий путь к добавить пойло для всех 4 -й направлений является:

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

Это можно сделать, просто объявив одну функцию, которая будет обрабатывать все ваши направления UISwipeGestureRecognizer. Вот мой код:

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)

Вот функция, которая будет обрабатывать функциональность смахивания:

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

Вот так: ( 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
Добавьте описание к своему коду, чтобы он стал лучше.
Poul Bak

0

Для Swift 5 обновлено

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

    }

Как это ответ на вопрос ОП? Проблема заключалась в том, чтобы найти элегантный способ добавить несколько направлений в распознаватель жестов смахивания.
шашват
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.