navigate between tab bar using swipe gesture - ios

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

Here is a slightly modified version of an earlier suggestion that is ready for Swift 5 and iOS 12.
The real advantages are:
it uses guard statements so you don't have to mess with unwrapping the tabBarController and the viewControllers in the handler
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 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 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.

Related

Can't recognize UISwipeGesture on my ScrollView

In my app, there is a scrollView(pageScrollView) which is a snapchat like interface (https://www.youtube.com/watch?v=1_daE3IL_1s)
However, when I try to use below code to get the gesture on the scroll view, it cannot detect, can anyone help me on this??
let leftSwipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(leftSwipedByUser(_:)))
leftSwipeGesture.direction = .left
self.pageScrollView.addGestureRecognizer(leftSwipeGesture)
let rightSwipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(rightSwipedByUser(_:)))
rightSwipeGesture.direction = .right
self.pageScrollView.addGestureRecognizer(rightSwipeGesture)
And the action is below:
#objc func leftSwipedByUser(_ gesture:UISwipeGestureRecognizer) {
print("left swipe")
}
#objc func rightSwipedByUser(_ gesture:UISwipeGestureRecognizer) {
print("right swipe")
}

tab bar slide animation swift 4

I want to add animation to the tab swipe. How can it be done in swift 4 without using any library?
I have two tabs I swipe in the screen right or left its change the tab bar.
How would I make it so it looks like it is sliding to the right or left tab bar rather than just instantly changing the tab-bar.
Also, I have defined the gesture separately in FirstViewController & SecondViewController. Is there a way to define it at one place and call it. #newToSwift
import UIKit
class FirstViewController: UIViewController {
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
view.addGestureRecognizer(leftSwipe)
view.addGestureRecognizer(rightSwipe)
}
#objc func handleSwipes(_ sender:UISwipeGestureRecognizer) {
print(sender.direction);
if sender.direction == .left {
if (self.tabBarController?.selectedIndex)! < 2 { // set your total tabs here
self.tabBarController?.selectedIndex += 1
}
} else if sender.direction == .right {
if (self.tabBarController?.selectedIndex)! > 0 {
self.tabBarController?.selectedIndex -= 1
}
}
}
}
This is second ViewController.
// SecondViewController.swift
import UIKit
class SecondViewController: UIViewController {
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
view.addGestureRecognizer(leftSwipe)
view.addGestureRecognizer(rightSwipe)
}
#objc func handleSwipes(_ sender:UISwipeGestureRecognizer) {
print(sender.direction);
if sender.direction == .left {
if (self.tabBarController?.selectedIndex)! < 2 { // set your total tabs here
self.tabBarController?.selectedIndex += 1
}
} else if sender.direction == .right {
if (self.tabBarController?.selectedIndex)! > 0 {
self.tabBarController?.selectedIndex -= 1
}
}
}
}
I suppose you could create your own UITabBarController subclass and add the gesture recognizers to its view and take it from there. Should work the same as the code you shared.

How do I create a UISwipeGestureRecognizer programatically

private let swipeUp: UISwipeGestureRecognizer = {
let swiper = UISwipeGestureRecognizer(target: self, action: #selector(movedUp))
swiper.direction = .up
return swiper
}()
private let swipeDown: UISwipeGestureRecognizer = {
let swiper = UISwipeGestureRecognizer(target: self, action: #selector(movedDown))
swiper.direction = .down
return swiper
}()
creating my swipeUp and swipeDown gesture recognizers
func movedUp(sender: UISwipeGestureRecognizer){
print("UP")
}
func movedDown(sender: UISwipeGestureRecognizer){
print("DOWN")
}
my functions to be called when the swipe is recieved
override func viewDidLoad() {
self.view.addGestureRecognizer(swipeUp)
self.view.addGestureRecognizer(swipeDown)
}
adding my gesture recognizers in viewDidLoad
my program runs, but nothing happens when i swipe, what am i doing wrong?
Thankyou everyone
Try this:
private lazy var swipeUp: UISwipeGestureRecognizer = {
let swiper = UISwipeGestureRecognizer(target: self, action: #selector(movedUp))
swiper.direction = .up
return swiper
}()
private lazy var swipeDown: UISwipeGestureRecognizer = {
let swiper = UISwipeGestureRecognizer(target: self, action: #selector(movedDown))
swiper.direction = .down
return swiper
}()
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addGestureRecognizer(swipeUp)
self.view.addGestureRecognizer(swipeDown)
}
func movedUp(sender: UISwipeGestureRecognizer)
{
print("UP")
}
func movedDown(sender: UISwipeGestureRecognizer)
{
print("DOWN")
}
Have you tried func movedUp(sender: UIGestureRecognizer)

How to use pan gesture and a swipe gesture alternatively on the same view?

I have a view that contains a counter.
I have implemented two different gesture recognizers,
a UISwipeGesture to increase the count by one,
and a UIPanGesture in order to increase the count by multiple numbers every
time the user swipes up.
Both gestures work, but my problem is they don't work at the same time.
I want them to work alternatively, for example if I do small swipes the
counter should increase by one, and if I keep dragging upwards the counter
should increase by multiple numbers.
Here's part of my code:
```
override func viewDidLoad() {
super.viewDidLoad()
setupSwipeGestures()
setupPanGestures()
}
private func setupSwipeGestures() {
let swipeUp = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:"))
let swipeDown = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:"))
swipeUp.direction = .Up
swipeDown.direction = .Down
circleView.addGestureRecognizer(swipeUp)
circleView.addGestureRecognizer(swipeDown)
}
private func setupPanGestures() {
let panGesture = UIPanGestureRecognizer(target: self, action: Selector("handleThePan:"))
circleView.addGestureRecognizer(panGesture)
}
extension UIPanGestureRecognizer {
func isDown(circleView: UIView) -> Bool {
let velocity : CGPoint = velocityInView(circleView)
if velocity.y < 0 {
print("ex Gesture went up")
return false
} else {
print("ex Gesture went down")
return true
}
}
}
```
P.S: The methods "handleSwipe" and "handlePan" contain the logic of the counter.
A swipe and a pan gesture can not be recognized at the same time because a swipe gesture is just a special type of pan that has to be faster, short lived, and in one direction.
What you should do is setup the pan gestures to require the swipe gesture to fail before they can start. You will need to set each of the UISwipeGestureRecognizer to be a requireGestureRecognizerToFail on the UIPanGestureRecognizer
override func viewDidLoad() {
super.viewDidLoad()
let swipeGestures = setupSwipeGestures()
setupPanGestures(swipeGestures: swipeGestures)
}
private func setupSwipeGestures() -> [UISwipeGestureRecognizer] {
let swipeUp = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:"))
let swipeDown = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:"))
swipeUp.direction = .Up
swipeDown.direction = .Down
circleView.addGestureRecognizer(swipeUp)
circleView.addGestureRecognizer(swipeDown)
return [swipeUp, swipeDown]
}
private func setupPanGestures(swipeGestures: [UISwipeGestureRecognizer]) {
let panGesture = UIPanGestureRecognizer(target: self, action: Selector("handleThePan:"))
for swipeGeature in swipeGestures {
panGesture.requireGestureRecognizerToFail(swipeGesture)
}
circleView.addGestureRecognizer(panGesture)
}
Swift 3
override func viewDidLoad() {
super.viewDidLoad()
let swipeGestures = setupSwipeGestures()
setupPanGestures(swipeGestures: swipeGestures)
}
private func setupSwipeGestures() -> [UISwipeGestureRecognizer] {
let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.handleSwipes))
let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.handleSwipes))
swipeUp.direction = .up
swipeDown.direction = .down
circleView.addGestureRecognizer(swipeUp)
circleView.addGestureRecognizer(swipeDown)
return [swipeUp, swipeDown]
}
private func setupPanGestures(swipeGestures: [UISwipeGestureRecognizer]) {
let panGesture = UIPanGestureRecognizer.init(target: self, action:#selector(self.handleThePanUp))
for swipeGesture in swipeGestures {
panGesture.require(toFail: swipeGesture)
}
circleView.addGestureRecognizer(panGesture)
}

Change iOS view / view controller using swipe gesture

How can I implement a swipe gesture to change view to and fro?
The best example I've seen so far is the Soundcloud application but I couldn't figure out how to make it work.
Compatible with Swift 5
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
view.addGestureRecognizer(leftSwipe)
view.addGestureRecognizer(rightSwipe)
}
#objc func handleSwipes(_ sender: UISwipeGestureRecognizer)
{
if sender.direction == .left
{
print("Swipe left")
// show the view from the right side
}
if sender.direction == .right
{
print("Swipe right")
// show the view from the left side
}
}
Use this code...
override func viewDidLoad() {
super.viewDidLoad()
var swipeRight = UISwipeGestureRecognizer(target: self, action: "respondToSwipeGesture:")
swipeRight.direction = UISwipeGestureRecognizerDirection.Right
self.view.addGestureRecognizer(swipeRight)
}
func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizerDirection.Right:
println("Swiped right")
//change view controllers
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let resultViewController = storyBoard.instantiateViewControllerWithIdentifier("StoryboardID") as ViewControllerName
self.presentViewController(resultViewController, animated:true, completion:nil)
default:
break
}
}
}
You can a UISwipeGestureRecognizer to your UIView and add to this gesture a target and an action to perform when the gesture occurs
var swipeGesture = UISwipeGestureRecognizer(target: self, action: "doSomething")
myView.addGestureRecognizer(swipeGesture)
func doSomething() {
// change your view's frame here if you want
}
This tutorial might be helpful to you: http://www.avocarrot.com/blog/implement-gesture-recognizers-swift/
Basically, you'll need to add a gesture recognizer to your view that listens for swipe gestures. Then when it detects a swipe, push to the next view.

Resources