'Detect page change in UICollectionView
I tried finding this question for a while but could not find this problem's answer.
My problem is that i have a UICollectionView and the Scroll Direction is Horizontal with Paging Enabled. My problem is that i want to keep the tack of the current page number on which the user is, so i created an int variable and now want to add or subtract it by 1 each time the user swipes right or left. I tried using scrollView's delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
but when the user swipes right or left, it is called as many number of the times as the number of columns on a page in the UICollectionView plus it wont let me know that whether the user went to the next page or the previous one.
Solution 1:[1]
Swift 3 Xcode 8.2
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let x = scrollView.contentOffset.x
let w = scrollView.bounds.size.width
let currentPage = Int(ceil(x/w))
// Do whatever with currentPage.
}
Solution 2:[2]
Based on @Shankar BS 's answer I've implemented it like this in Swit. Keep in mind that CollectionViewDelegate conforms to ScrollViewDelegate:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageWidth = scrollView.frame.size.width
let page = Int(floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)
print("page = \(page)")
}
Solution 3:[3]
You can get the current page like below, index will be from 0 to (total page - 1)
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
NSLog(@"Current page -> %d",page);
}
Solution 4:[4]
SWIFT 5
For example, put this method in your ViewController with extensions UICollectionViewDelegate,UICollectionViewDataSource
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageWidth = scrollView.frame.size.width
let page = Int(floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)
print("page = \(page)")
}
Solution 5:[5]
Swift 2.2
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
let x = collectionView.contentOffset.x
let w = collectionView.bounds.size.width
let currentPage = Int(ceil(x/w))
print("Current Page: \(currentPage)")
}
Solution 6:[6]
You can get the currentPage this way when the user end the dragging:
Swift 5.6 Tested and works!
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let itemWidth = collectionView.frame.width // Get the itemWidth. In my case every cell was the same width as the collectionView itself
let contentOffset = targetContentOffset.pointee.x
let targetItem = lround(Double(contentOffset/itemWidth))
let targetIndex = targetItem % YOUR_ARRAY.count // numberOfItems which shows in the collection view
print(targetIndex)
}
Solution 7:[7]
Xamarin.iOS:
You can override DecelerationEnded method of UICollectionViewDelegate or subscribe to DecelerationEnded event of UICollectionView (custom delegate will be used under the hood).
public override void DecelerationEnded(UIScrollView scrollView)
{
var x = scrollView.ContentOffset.X;
var w = scrollView.Bounds.Size.Width;
var currentPage = Math.Ceiling(x / w);
// use currentPage here
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | shim |
| Solution 2 | Graham Perks |
| Solution 3 | shim |
| Solution 4 | |
| Solution 5 | Jonni Ã…kesson |
| Solution 6 | SwiftiSwift |
| Solution 7 | wcoder |
