0

I have a controller that contains a UICollectionView called myCollection:

public lazy var myCollection : UICollectionView = {
    let routine = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout());
    let routineLayout = UICollectionViewFlowLayout()
    routineLayout.scrollDirection = .horizontal
    routine.collectionViewLayout = routineLayout
    routine.decelerationRate = UIScrollView.DecelerationRate.fast
    routine.translatesAutoresizingMaskIntoConstraints = false
    routine.delegate = self
    routine.dataSource = self
    routine.backgroundColor = .clear
    routine.register(MyCellView.self, forCellWithReuseIdentifier: cellId)
    routine.isPagingEnabled = true
    routine.showsHorizontalScrollIndicator = false
    routine.showsVerticalScrollIndicator = false
    routine.layer.cornerRadius = 20
    routine.layer.masksToBounds = true
    return routine
}()

I add this collectionView as a subview to my app, using these constraints:

NSLayoutConstraint.activate([
        myCollection.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        myCollection.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
        myCollection.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor, multiplier: 1),
        myCollection.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor, multiplier: 0.40)
])

For the sake of completeness, here is the code that shows cell size is 100% of the parent view with no spacing.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: collectionView.frame.width, height: collectionView.frame.height)
}

When I implement the scrollViewWillEndDragging function using above constraints, I get the right index printed out for the collection cell:

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    let navigatedTo =  Int(targetContentOffset.pointee.x) / Int(myCollection.frame.width)
}

However, when I reduce the size of myCollection, the right index is no longer printed out. For example:

view.safeAreaLayoutGuide.widthAnchor, multiplier: 0.90

I cannot figure out how to account for this horizontal compression in scrollViewWillEndDragging. The best guide I've found thus far is here : Snap to center of a cell when scrolling UICollectionView horizontally , but I am not able to connect the ideas together to account for this compression.

angryip
  • 2,140
  • 5
  • 33
  • 67
  • Are you sure? I did a quick test and it seems to work as expected: https://pastebin.com/R54QCgzz – DonMag Oct 21 '21 at 12:38
  • @DonMag is this true for when you scroll left or right very quickly? – angryip Oct 21 '21 at 13:41
  • Running that code from my pastebin, the label always shows the correct item index. I changed the number of items to 100, so I could flip-flip-flip through a **lot** of cells, and I still get the correct number in the label. – DonMag Oct 21 '21 at 14:19
  • Interesting; Not sure why I do not. If I scroll to the right (1->100) super-fast, everything is fine. If I scroll to the left ( 100->1 ) super-fast, it skips several cells at a time. – angryip Oct 21 '21 at 14:39
  • Do you mean ***while*** you're "super-fast scrolling" it "skips" numbers, but when you ***stop*** the correct index is shown? – DonMag Oct 21 '21 at 14:46
  • @DonMag While I am super-fast scrolling, it skips numbers and when i stop, it remains at the wrong number. As if the cells in between did not exist in the first place. If I print out the targetContentOffset.pointee.x as I go, there is a clear jump in it's value ( by 2 cell sizes, or 3 ) – angryip Oct 21 '21 at 14:49
  • Do you see a difference if you use `scrollViewDidEndDragging` instead of `scrollViewWillEndDragging`? – DonMag Oct 21 '21 at 14:54
  • @DonMag Good question. I'll give it a try tonight and reply with my observations. From your perspective, you never enter a buggy state ( regardless of the direction or the velocity of the swipe )? – angryip Oct 21 '21 at 14:58
  • No, I can't seem to get it to miss or show the wrong index. I've tried on simulator and a couple devices (iOS 13 and 14). Are you running this on `iOS 15`? *Maybe* that affects it? I edited my pastebin slightly, to record the `targetContentOffset.pointee.x` and the `navigatedTo` value each time it's called, with the "info label" scrollable. Maybe that could help you debug what might be going on. – DonMag Oct 21 '21 at 15:09
  • @DonMag I am using iOS 15. Maybe that is the missing discrepancy in observation. I have a few devices running an over version and will have to try it on them as well. – angryip Oct 21 '21 at 15:11

0 Answers0