简体   繁体   中英

navigate between tab bar using swipe gesture

I want to navigate between my tab bar using swipe gestures. What is the easiest way to do that? I tried something like this...

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

        }
}

If I try to swipe right nothing happens. The app crashes when swiping left the following error message

unrecognized selector sent to instance 0x7f924380a730

Well if you want to navigate through you tabBar you should implement a swipeGestureRecognizer for .left and .right and then work with the tabBarController?.selectedIndex , something like this:

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

Here's a Swift4 example of swiping left and right right through a TabBar controller.

Things I don't like about this solution: - seems like you should be able to register the handler once and distinguish the direction within the handler itself but I wasn't able to easily do that. - I'm also curious how to do a gesture that includes a drag for visual effect. I'm think I need to include a PanGesture as well in order to pull that off.

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)

}

And then the handler:

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

try using the Swift 4 selector syntax:

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

Here is a slightly modified version of an earlier suggestion that is ready for Swift 5 and iOS 12.

The real advantages are:

  1. it uses guard statements so you don't have to mess with unwrapping the tabBarController and the viewControllers in the handler
  2. it doesn't require a hard-coded number of tabs — it just gets it from the viewControllers array.

I also cleaned it up a bit to make it a little less verbose. It has been tested with Swift 5 running on iOS 12 (and it should be fine on iOS 11.4, since that was my minimum deployment version that this was tested on).

Add these to viewDidLoad (or other appropriate location of your choosing):

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)

Then add this as your handler for the events:

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

Try using the Swift 3 selector syntax:

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

like so

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 introduced this feature to enable the compiler to check whether the function you're specifying actually exists. It is therefore much saver than the concepts before.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM