ScrollToItem isn't working properly

Viewed 1589

I have a horizontal collection view of buttons. When one of them is clicked, the user is taken to another view controller. Often times not all buttons are visible, so what I would like, is for the selected button to be of the left most side of the collection view.

I was attempting to do that with the scrollToItem function. The problem is, that it keeps scrolling the collection view all the way to the right each time.

Relevant code:

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

//frees up the collection view when the scroll is active
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
    isScrolling = true
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)

    //possible problem
    if isScrolling == false {
        collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.left, animated: false)
    }

    let myLabel = cell.viewWithTag(1) as! UILabel

    let myArray = labelArray[indexPath.row]

    myLabel.text = labelArray[indexPath.row]
    myLabel.textColor = UIColor.white

    if myArray == labelArray[1] {
        cell.backgroundColor = UIColor.black
    } else {
        cell.backgroundColor = UIColor(red: 56/255, green: 120/255, blue: 195/255, alpha: 1)
    }

    return cell
}

Any help would be greatly appreciated.

2 Answers

You are calling the scrollToItem method in the cellForItemAt method, which is called for every visible cell in your collection view. So you are essentially trying to scroll to each cell as it becomes visible. Try calling the scrollToItem method in the didSelectItemAt method like this:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    collectionView.scrollToItem(at: indexPath, at: .left, animated: true)
}

The didSelectItemAt is only called when a cell is selected and provides the IndexPath of the selected cell.

I got it to work. All I did was change

if isScrolling == false {
    collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.left, animated: false)
}

to

if isScrolling == false {
    let i = IndexPath(item: 1, section: 0)
    collectionView.scrollToItem(at: i, at: .right, animated: false)
}

Previously it would scroll to each cell without stopping at each individual one.

So for each item I hard code the value dependent on which section that is selected.

Related