0

Hi I'm trying to add feedback when scrolling through the collectionview Items. Where should I add code for feedback in collectionview delegates. If I add in willDisplay then add cell that will be displayed initially will call feedback which is not good. I need to provide feedback only when the user scrolls and selects a item.

Arun K
  • 810
  • 2
  • 12
  • 33

2 Answers2

3

Assuming that you only scroll in one direction (like vertically) and that all rows of items have the same height, you can use scrollViewDidScroll(_:) to detect selections like UIPickerView.

class ViewController {
    var lastOffsetWithSound: CGFloat = 0
}

extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if let flowLayout = ((scrollView as? UICollectionView)?.collectionViewLayout as? UICollectionViewFlowLayout) {
            let lineHeight = flowLayout.itemSize.height + flowLayout.minimumLineSpacing
            let offset = scrollView.contentOffset.y
            let roundedOffset = offset - offset.truncatingRemainder(dividingBy: lineHeight)
            if abs(lastOffsetWithSound - roundedOffset) > lineHeight {
                lastOffsetWithSound = roundedOffset
                print("play sound feedback here")
            }
        }
    }
}

Remember that UICollectionViewDelegateFlowLayout inherits UICollectionViewDelegate, which itself inherits UIScrollViewDelegate, so you can declare scrollViewDidScroll in any of them.

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 1
    Thanks. I'll check if this meets my requirement. – Arun K May 21 '19 at 15:04
  • @ArunK also, if you want to **snap** at fixed positions when scrolling like a UIPickerView, you'll need to implement _paging_-like scrolling. This is explained in other questions/answers on Stack Overflow. – Cœur May 21 '19 at 17:48
  • 1
    I would suggest using `>= lineHeight`. Otherwise, it skips some cells – Mike Jul 18 '20 at 08:28
0

You can add it in view controller methods

touchesBegan(_:with:)
touchesMoved(_:with:)

So that whenever the user interacts with your view controller anywhere you can provide a feedback and it will only be limited to user interaction and not when you add a cell programetically or call update on your table view.

If you have other UI components as well in your controller and you want to limit the feedback to your collection view and not other components then you can check the view in these methods.

let touch: UITouch = touches.first as! UITouch
if (touch.view == collectionView){
    println("This is your CollectionView")
}else{
    println("This is not your CollectionView")
}

Don't forget to call super to give system a chance to react to the methods. Hope this helps.

nishith Singh
  • 2,968
  • 1
  • 15
  • 25