如何识别所有 4 个方向的滑动

Posted

技术标签:

【中文标题】如何识别所有 4 个方向的滑动【英文标题】:How to recognize swipe in all 4 directions 【发布时间】:2014-08-04 14:11:45 【问题描述】:

我需要使用滑动来识别滑动手势向下然后向右。但是在swift UISwipeGestureRecognizer 有预先确定的正确方向..我不知道如何使它用于其他方向..

【问题讨论】:

【参考方案1】:
import UIKit

class ViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        let leftside = UISwipeGestureRecognizer(target: self, action: #selector(swiped))
        leftside.direction = .left
        view.addGestureRecognizer(leftside)
        
        let rightside = UISwipeGestureRecognizer(target: self, action: #selector(swiped))
        rightside.direction = .right
        view.addGestureRecognizer(rightside)
        
        
        let upside =  UISwipeGestureRecognizer(target: self, action: #selector(swiped))
        upside.direction = .up
        view.addGestureRecognizer(upside)
        
        let downside = UISwipeGestureRecognizer(target: self, action: #selector(swiped))
        downside.direction = .down
        view.addGestureRecognizer(downside)
        
        // Do any additional setup after loading the view, typically from a nib.
    
    @objc func swiped(gesture: UIGestureRecognizer)
        if let swipeGesture = gesture as? UISwipeGestureRecognizer
            switch swipeGesture.direction
            case UISwipeGestureRecognizer.Direction.left:
                view.backgroundColor = UIColor.red
            case UISwipeGestureRecognizer.Direction.right:
                view.backgroundColor = UIColor.yellow
            case UISwipeGestureRecognizer.Direction.up:
                view.backgroundColor = UIColor.green
            case UISwipeGestureRecognizer.Direction.down:
                view.backgroundColor = UIColor.blue
               
            default:
                "ERROR"
                
            
        
    


【讨论】:

代码在附有解释时会更有帮助。 Stack Overflow 是关于学习的,而不是提供 sn-ps 来盲目复制和粘贴。请edit您的问题并解释它如何回答所提出的具体问题。见How to Answer。【参考方案2】:

编辑:“swift5.3”

首先创建一个baseViewController并添加viewDidLoad这个代码:

class BaseViewController: UIViewController              

     override func viewDidLoad() 
         super.viewDidLoad()
          let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(swiped))
          swipeRight.direction = .right
          self.view.addGestureRecognizer(swipeRight)
          let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(swiped))
          swipeLeft.direction = .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.    

【讨论】:

【参考方案3】:

来自故事板:

    在您的视图中添加四个滑动手势识别器。 从属性检查器设置每个目标方向。你可以 选择右、左、上或下 一一选择滑动手势识别器,控制+拖动到你的视图控制器。插入名称(让我们说 leftGesture、rightGesture、upGesture 和 downGesture),将连接更改为:操作并键入: 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")
  

【讨论】:

通过这个答案,您不需要编写大量代码,但您可以使用情节提要以及情节提要和代码之间的连接。如果开发人员更喜欢以这种方式工作,这个答案可能会更容易,但如果开发人员更喜欢在编码方面工作,那么第一个答案肯定是最好的。 我使用了 4 个滑动手势而不是一个,并且很多工作量都在故事板中而不是编码中。【参考方案4】:

每个方向都需要一个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
        
    

【讨论】:

“每个识别器只能处理一个方向” - 这不是真的。见***.com/questions/16184539/… "每个识别器只能处理一个方向" - 具体来说,在 Swift 中为 true,在 Objective-C 中为 false。 您不必在.Down 等前面添加UISwipeGestureRecognizerDirection。如果足够,只需使用swipeDown.direction = .Down。只是一个提示 =) 我们可以将相同的gestureRecogniser对象添加到多个视图吗?我尝试过但没有成功。 如果你在 swift 中执行@Sergey Skoblikovs 的方法(通过执行swipe.direction = [.Right,.Down,.Up,.Left]),识别器甚至不会被调用,也许这是 swift 的一个问题,但目前不起作用.【参考方案5】:

滑动手势到你想要的视图,或者基于@Alexandre Cassagne的Swift 5和XCode 11中的viewcontroller整个视图

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

【讨论】:

【参考方案6】:

在 Swift 5 中,

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

【讨论】:

【参考方案7】:

挖了一会之后:

为所有 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

【讨论】:

【参考方案8】:

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)

    

【讨论】:

如何回答 OP 的问题?问题是要找到一种优雅的方式来向滑动手势识别器添加多个方向。【参考方案9】:

滑动手势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")
    

【讨论】:

【参考方案10】:

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

这样你可以写下剩余的方向,请注意是否有从下到上滚动视图,反之亦然

如果您有滚动视图,您将获得 conflict 从上到下并查看相反的手势。

【讨论】:

【参考方案11】:

就这样:(Swift 4.2.1)

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

【讨论】:

在您的代码中添加一些描述,这样会更好。【参考方案12】:

简单。只需按照下面的代码即可享受。

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

【讨论】:

【参考方案13】:

这可以通过简单地声明一个函数来处理你所有的滑动 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
        
    

【讨论】:

【参考方案14】:

Nate 的回答只是一个更酷的 swift 语法:

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

【讨论】:

【参考方案15】:

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

来自Alexandre Cassagne's approach的便捷方式

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

【讨论】:

使用此特定版本,您需要在终端中运行 defaults write com.apple.dt.xcode IDEPlaygroundDisableSimulatorAlternateFramebuffer -bool YES 以修复某些硬件上的错误。它应该在新版本的 Xcode 中修复【参考方案16】:

UISwipeGestureRecognizer 有一个 direction 属性,其定义如下:

var direction: UISwipeGestureRecognizerDirection

此手势识别器允许的滑动方向。


Swift 3.0.1(及以下)的问题在于,即使UISwipeGestureRecognizerDirection 符合OptionSet,以下 sn-p 将编译但不会产生任何积极的预期结果:

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

作为一种解决方法,您必须为每个所需的 direction 创建一个 UISwipeGestureRecognizer


以下 Playground 代码展示了如何使用 Array 的 map 方法为同一个 UIView 和同一个 selector 实现多个 UISwipeGestureRecognizer

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)【参考方案17】:

看起来情况最近发生了变化。在 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)

ios 8.4 和 9.2 的模拟器以及 9.2 的实际设备上测试。

或者,使用 mlcollard 的便捷扩展 here:

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


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

【讨论】:

可能调用了选择器,但是发送方的方向不正确。换句话说,如果您不需要知道滑动的方向但不需要知道滑动的方向,这种方法很好。 不再有效。在 Swift 3 中,上下文必须提供给第一个值:[UISwipeGestureRecognizerDirection.right, .left, .up, .down]【参考方案18】:

我只是想贡献这个,最后看起来更优雅:

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)

【讨论】:

self.addGestureRecognizer(gesture) 对我造成了错误。修复它的是self.view.addGestureRecognizer(gesture); @ahitt6345 我在UIView 子类中使用我的代码,但如果你在UIViewController 中,那你是绝对正确的! 干净,对我来说最好的答案。

以上是关于如何识别所有 4 个方向的滑动的主要内容,如果未能解决你的问题,请参考以下文章

滑动手势识别器在垂直方向上不起作用

如何使用 2 个手势识别器同时接收事件?

手势识别器滑动以从核心数据中删除

UIPanGestureRecognizer 的问题

改变滑动手势识别器的过渡

UISwipeGestureRecognizer 左方向无法识别