Swipe Left/Right on collectionView not called whil

2019-06-19 01:16发布

问题:

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

EDIT 1

Solved, for solutions click here

回答1:

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.



回答2:

Try following code it may helps you.

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

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

    cell.lable.text = self.items[indexPath.item]
    cell.backgroundColor = UIColor.yellowColor()
    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.leftSwiped))
    swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
    cell.addGestureRecognizer(swipeLeft)

    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.rightSwiped))
    swipeRight.direction = UISwipeGestureRecognizerDirection.Right
    cell.addGestureRecognizer(swipeRight)

    return cell
}


回答3:

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.



回答4:

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