【问题标题】:navigate between tab bar using swipe gesture使用滑动手势在标签栏之间导航
【发布时间】:2017-05-28 20:35:51
【问题描述】:

我想使用滑动手势在标签栏之间导航。最简单的方法是什么?我尝试过这样的事情......

import UIKit

class postAdViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        var leftSwipe = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:"))
        view.addGestureRecognizer(leftSwipe)    
    }

    func handleSwipes(sender:UISwipeGestureRecognizer) {
        if (sender.direction == .left) {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "favourireviewcontroller") as! UIViewController
            self.present(vc, animated: true, completion: nil)
        }
        if (sender.direction == .right) {

        }
}

如果我尝试向右滑动,则没有任何反应。滑动时应用崩溃并留下以下错误消息

无法识别的选择器发送到实例 0x7f924380a730

【问题讨论】:

    标签: ios swift swift3 xcode8 swipe


    【解决方案1】:

    如果你想在tabBar 中导航,你应该为.left.right 实现swipeGestureRecognizer,然后使用tabBarController?.selectedIndex,如下所示:

    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)
    
    func swiped(_ gesture: UISwipeGestureRecognizer) {
        if gesture.direction == .left {
            if (self.tabBarController?.selectedIndex)! < 2 { // set your total tabs here
                self.tabBarController?.selectedIndex += 1
            }
        } else if gesture.direction == .right {
            if (self.tabBarController?.selectedIndex)! > 0 {
                self.tabBarController?.selectedIndex -= 1
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是一个在 TabBar 控制器中左右滑动的 Swift4 示例。

      我不喜欢这个解决方案的地方: - 似乎您应该能够注册一次处理程序并区分处理程序本身的方向,但我无法轻松做到这一点。 - 我也很好奇如何做一个包含拖动视觉效果的手势。我认为我还需要包含一个 PanGesture 才能实现这一目标。

      override func viewDidLoad() {
          super.viewDidLoad()
      
          let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(_:)))
          let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(_:)))
          leftSwipe.direction = .left
          rightSwipe.direction = .right
          self.view.addGestureRecognizer(leftSwipe)
          self.view.addGestureRecognizer(rightSwipe)
      
      }
      

      然后是处理程序:

      @objc func handleSwipes(_ sender:UISwipeGestureRecognizer) {
          if sender.direction == .left {
              self.tabBarController!.selectedIndex += 1
          }
          if sender.direction == .right {
              self.tabBarController!.selectedIndex -= 1
          }
      }
      

      【讨论】:

        【解决方案3】:

        这是对早期建议稍作修改的版本,适用于 Swift 5 和 iOS 12。

        真正的优势是:

        1. 它使用guard 语句,因此您不必在处理程序中解开tabBarControllerviewControllers
        2. 它不需要硬编码的选项卡数量 - 它只是从 viewControllers 数组中获取它。

        我还对其进行了一些清理以使其不那么冗长。它已经在 iOS 12 上运行 Swift 5 进行了测试(在 iOS 11.4 上应该没问题,因为这是我测试过的最低部署版本)。

        将这些添加到viewDidLoad(或您选择的其他适当位置):

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

        然后将其添加为事件的处理程序:

        @objc func handleSwipeGesture(_ gesture: UISwipeGestureRecognizer) {
          guard let tabBarController = tabBarController, let viewControllers = tabBarController.viewControllers else { return }
          let tabs = viewControllers.count        
          if gesture.direction == .left {
              if (tabBarController.selectedIndex) < tabs {
                  tabBarController.selectedIndex += 1
              }
          } else if gesture.direction == .right {
              if (tabBarController.selectedIndex) > 0 {
                  tabBarController.selectedIndex -= 1
              }
          }
        }
        

        【讨论】:

        • 感谢代码,滑动不是动画,你知道如何动画吗?
        【解决方案4】:

        尝试使用 Swift 4 选择器语法:

        //below code write in view did appear()
        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)
          // below code create swipe gestures function
        
          // MARK: - swiped
           @objc  func swiped(_ gesture: UISwipeGestureRecognizer) {
            if gesture.direction == .left {
                if (self.tabBarController?.selectedIndex)! < 2
                { // set here  your total tabs
                    self.tabBarController?.selectedIndex += 1
                }
            } else if gesture.direction == .right {
                if (self.tabBarController?.selectedIndex)! > 0 {
                    self.tabBarController?.selectedIndex -= 1
                }
            }
        }
        

        【讨论】:

          【解决方案5】:

          尝试使用Swift 3 选择器语法:

          let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(_:))
          

          像这样

          override func viewDidLoad() {
              super.viewDidLoad()
          
              nextButton.layer.cornerRadius = 7
          
              let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(_:))
              //leftSwipe.direction = .right
              view.addGestureRecognizer(leftSwipe)
          }
          
          
          
          func handleSwipes(_ sender: UISwipeGestureRecognizer) {
              if (sender.direction == .left) {
                  let storyboard = UIStoryboard(name: "Main", bundle: nil)
                  let vc = storyboard.instantiateViewController(withIdentifier: "favourireviewcontroller") as! UIViewController
                  self.present(vc, animated: true, completion: nil)
              }
          
              if (sender.direction == .right) {
          
              }
          }
          

          Swift 3 引入了此功能,使编译器能够检查您指定的function 是否确实存在。因此,它比之前的概念要节省很多。

          【讨论】: