Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swipe Left/Right on collectionView not called while scrolling vertically

I have a collectionView with vertical scrolling, covering whole screen on the device (i.e fullscreen).

I have register the Swipe Left and Right gestures for my collectionView.

//------------right  swipe gestures in collectionView--------------//
    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.rightSwiped))
    swipeRight.direction = UISwipeGestureRecognizerDirection.Right
    self.collectionView.addGestureRecognizer(swipeRight)

    //-----------left swipe gestures in collectionView--------------//
    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.leftSwiped))
    swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
    self.collectionView.addGestureRecognizer(swipeLeft)

Problem: Swipe left and right gestures callback does not fire while collectionView is scrolling vertically.

Is there any simple workaround for this.

here is my whole ViewController Class

import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {




@IBOutlet weak var collectionView: UICollectionView!

let reuseIdentifier = "cell" // also enter this string as the cell identifier in the storyboard
var items = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48"]


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    collectionView.dataSource = self
    collectionView.delegate = self


    //------------right  swipe gestures in collectionView--------------//
    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.rightSwiped))
    swipeRight.direction = UISwipeGestureRecognizerDirection.Right
    self.collectionView.addGestureRecognizer(swipeRight)

    //-----------left swipe gestures in collectionView--------------//
    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.leftSwiped))
    swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
    self.collectionView.addGestureRecognizer(swipeLeft)


}


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return self.items.count
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    // get a reference to our storyboard cell
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CustomCell

    // Use the outlet in our custom class to get a reference to the UILabel in the cell
    cell.lable.text = self.items[indexPath.item]
    cell.backgroundColor = UIColor.yellowColor()

    return cell
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    print(indexPath.row)
}

func rightSwiped()
{

    print("right swiped ")
}

func leftSwiped()
{

    print("left swiped ")

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

here is my collectionView look like

enter image description here

EDIT 1

Solved, for solutions click here

like image 336
Qadir Hussain Avatar asked Jul 13 '16 08:07

Qadir Hussain


3 Answers

The delegate of default gesture recognisers of the UICollcetionView is collection view object itself (obviously).

The default implementation of -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizerreturns YESin side the UICollectionView class.

So to address your problem ,you need to set the collection view object as delegate to your "left" and "right" swipe gesture recognisers as follows.

swipeRight.delegate = collectionView;
swipeLeft.delegate = collectionView;

This should make your rightSwiped() and leftSwiped() to get fired when corresponding swipe occurs.

like image 149
Hariprasad Avatar answered Nov 14 '22 14:11

Hariprasad


Here is very simple Solution

1)You need take a property to store previous content offset

2)Implement the delegate method ScrollViewDidScroll & compare current content Offset with previous content Offset

var contentOffset: CGFloat = 0

// MARK: UICollectionViewDelegate

func scrollViewDidScroll(scrollView: UIScrollView) {

   if contentOffset > scrollView.contentOffset.y {
   // scrolling up
   } else if contentOffset < scrollView.contentOffset.y {
   //scrolling Down
   }
    contentOffset = scrollView.contentOffset.y
}

3)It can be done without adding any gesture recognizer.

like image 1
Rohit Pradhan Avatar answered Nov 14 '22 12:11

Rohit Pradhan


Thanks @Hariprasad for pointing me shouldRecognizeSimultaneouslyWithGestureRecognizer

Here is the solution

I have subclass the UICollectionView and implemented the UIGestureRecognizerDelegate like below

import UIKit

class TouchCollectionView: UICollectionView, UIGestureRecognizerDelegate {

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
    // Drawing code
}
*/

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    let gesture = UIGestureRecognizer()
    gesture.delegate = self // Set Gesture delegate so that shouldRecognizeSimultaneouslyWithGestureRecognizer can be set to true on initialzing the UICollectionView
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}   
}
  • change the class property of your collectionView from identity inspector http://prntscr.com/bsqbq3

Whole ViewController will remain the same as mentioned in the question

like image 3
Qadir Hussain Avatar answered Nov 14 '22 13:11

Qadir Hussain