Reputation: 21
I've been trying to scroll UICollectionView
with horizontal scroll, to the next page when isPagingEnabled
property was set as true
. I've been working on it for couple of days and I've made a lot of research, but I couldn't find any case like mine. If you already had this problem and if you already found a solution for it, it would be great sharing your solution way with me. Here is my current case;
func sampleTest() {
let collectionView = app.collectionViews[.sampleCollectionView]
collectionView.waitUntil(.exists)
let totalPageCount = collectionView.cells.count
guard totalPageCount > 0 else {
XCTFail("No pages could find in collection to take snapshot.")
return
}
for currentPage in 1...totalPageCount {
snapshot("Page\(currentPage)")
collectionView.swipeLeft()
}
}
Here, swipeLeft()
method of XCUIElement
is not working as expected in my case. When I call the method, it is not moving to the next page. It swipes a little bit and turn back due to isPagingEnabled = true
statement.
In addition, there is another problem that collectionView.cells.count
is calculated wrong. It always returns 1. I assume that the reason of the problem is about reusability. Because the other cells has not dequeued yet. Or collectionView.cells.count
is not working as I guess?
Upvotes: 2
Views: 437
Reputation: 357
I had a similar issue where paging didn't play nicely with my UI tests, since my first cell had a left content inset and was centred, and the next cell was always peeking into view, so scrolling by the size of the bounds of the collectionView didn't give the intended results.
Instead, I disabled isPagingEnabled
on the collectionView and used these UIScrollViewDelegate
methods to 'snap to' the centre of the next cell to be shown, depending on which way the user (or test) was swiping:
var collectionViewContentOffsetXBeforeScrolling: CGFloat = 0.0
Record the content offset when it starts decelerating:
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
guard scrollView == collectionView else { return }
collectionViewContentOffsetXBeforeScrolling = scrollView.contentOffset.x
}
Centre the leftmost or rightmost cell currently in view:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView == collectionView {
let visibleIndexPaths = collectionView.indexPathsForVisibleItems.sorted(by: { $0.item < $1.item })
if let rightMostCell = visibleIndexPaths.last, let leftMostCell = visibleIndexPaths.first {
let indexPathToSelect = collectionView.contentOffset.x > collectionViewContentOffsetXBeforeScrolling ? rightMostCell: leftMostCell
let cellToBeCentered = collectionView.cellForItem(at: indexPathToSelect)
collectionView.scrollToItem(at: indexPathToSelect, at: .centeredHorizontally, animated: true)
}
}
Finally, I set bounces = false
to simplify the logic and prevent incorrect behaviour when the method was called at either end of the collectionView's cells.
Upvotes: 0