Navigate between the tab bar with swipe gestures
I want to navigate between my tab bar using gestures. What's the easiest way to do this? I've 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 slip, nothing happens. Application crashes while scrolling leaves an error message
unrecognized selector posted to instance 0x7f924380a730
Well, if you want to navigate through you tabBar
, you have to implement swipeGestureRecognizer
for .left
and .right
, and then work with 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 is a Swift4 example of swiping left and right through a TabBar controller.
What I don't like about this solution: - it seems like you should be able to register the handler once and discern the direction within the handler itself, but I couldn't easily do that. - I'm also curious about how to make a gesture that involves dragging for visual effect. I think I need to enable PanGesture to make this happen.
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 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
}
}
}
Try using the syntax Swift 3
:
let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(_:))
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 function to allow the compiler to check if an existing one exists function
. Therefore, it is much better than the concepts previously.
Here's a slightly modified version of an earlier proposal that's ready for Swift 5 and iOS 12.
Real benefits:
- it uses
guard
operators so you don't have to mess withtabBarController
andviewControllers
in the handler - it doesn't require a hardcoded number of tabs - it just gets it from an array
viewControllers
.
I've 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 that should be fine on iOS 11.4 as this was my minimal deployment version I tested this on).
Add them to viewDidLoad
(or some other suitable location of your choice):
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 event handler:
@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
}
}
}