简体   繁体   中英

Pan Gesture in UICollectionViewCell AND UICollectionView

I have a collection view of bars that can slide up and down. Each cell in the collection view is using a UIPanGestureRecognizer to control the blue bar sliding up and down. The collection view does not scroll here.

活性

There is an "edit mode" which disables the pan gesture controlling the bars. The hope here is that in "edit mode", the collection view can then scroll left and right.

编辑模式

My attempt at doing this was to disabled the pan gesture in each of the cells. I also tried using the UIGestureRecognizerDelegate methods to try to disable touches and fail the cell's pan gesture in favor of the collection view's pan gesture. It seems that the collection view's pan gesture is not forwarded to any of the cell's gesture delegate calls.

These delegate calls got me the closest (delegate for cell's pan gesture):

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    return !self.editMode  // bar doesn't need to pan in edit mode
}

With this implemented, I could pan the collection view if I started the pan in the white space between cells. Starting a pan on a cell would not do anything, though.

EDIT: I uploaded a sample project of the issue to github.

If I understand this correctly, I think the problem could be as follows:

  1. Your UICollectionView will listen for pan gestures. So far so good.
  2. In KBHBarSlider you add UIPanGestureRecognizer for you sliders. They have "priority" over the underlaying UICollectionView.

This actually makes sense as your BarSliders are above the CollectionView. My best take would be to let the BarSliders add the UIPanGestureRecognizer when needed, and have them completely removed when editing.

So first try and remove the gestureRecognizer you added in VOLBarSliderCell.

Then in KBHBarSlider add something like: (and make sure your init calls addPanRecognizer() instead of setup())

func addPanRecognizer() {
    let panGesture = UIPanGestureRecognizer(target: self, action: "viewDidPan:")
    self.gestureRecognizers = [panGesture]
}

func removePanRecognizer() {
  self.gestureRecognizers = []
}

It is now possible to add and remove the gestures on demand, do so from your edit get/set overrides in VOLBarSliderCell:

var editing: Bool = false {
    didSet {            
        if !self.editing {
            self.barSlider.addPanRecognizer()
            // Removed code, to keep this example short...
        } else {
            self.barSlider.removePanRecognizer()
            // Removed code, to keep this example short...
        }
    }
}

Try adding this code at VOLBarSliderCell:29:

self.panGesture.enabled = !self.editing

And remove:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    if self.editing && gestureRecognizer == self.panGesture {
        return false
    }

    return true
}

To be fair your problem was not clear to me, so I gave a try as an answer anyway since I cannot comment yet to request clarifications.

I understood you wanna scroll your UICollectionView while you are in edit mode. So that's what the code above does. If you wish to disable scrolling altogether UICollectionView while NOT editing then you can use scrollEnabled = false on the UICollectionView.

Clarify a bit better what is the problem you are trying to solve. That way you might be able to bring precise answers.

You're on the right track. Keep a reference to your leftRight gestureRecognizer. Then in shouldReceiveTouch, check if editing and the gestureRecognizer is your leftRight recognizer

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    if(self.editing && gestureRecognizer != self.leftRightRecognizer){
        return 0;
    }
    return 1; 
}

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