问题
I'm using a UICollectionView to scroll through a set of thumbnails quickly. Once scrolling ends, I'd like to display a larger hi-res version of the current thumbnail.
How can I detect when the user has completed scrolling? I do implement didEndDisplayingCell, but that only tells me when a particular cell has scrolled off; it doesn't tell me when the scroll motion actually completes.
回答1:
NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView
UICollectionView is a subclass of UIScrollView. So if you have set the delegate and implemented UIScrollViewDelegate, you should be able to detect this the same way as UIScrollView.
For eg:-
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
As per documentation, the above method should tell when the scroll view has ended decelerating the scrolling movement.
回答2:
Just to cover your bases you should implement both these UIScrollViewDelegate methods.
In some cases there may not be a deceleration (and scrollViewDidEndDecelerating would not be called), for e.g., the page is fully scrolled in place. In those case do your update right there in scrollViewDidEndDragging.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate) {
[self updateStuff];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self updateStuff];
}
回答3:
An important fact to note here :
This method gets called on User initiated scrolls (i.e a Pan gesture)
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
On the other hand, this one gets called on all manually (programatically) initiated scrolls (like scrollRectToVisible or scrollToItemAtIndexPath)
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
回答4:
Swift 3 version:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Your code here
}
回答5:
Swift 3 version of Abey M and D6mi 's answers:
When scroll is caused by user action
public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if (!decelerate) {
//cause by user
print("SCROLL scrollViewDidEndDragging")
}
}
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
//caused by user
print("SCROLL scrollViewDidEndDecelerating")
}
When scroll is caused by code action (programmatically): (like "scrollRectToVisible" or "scrollToItemAtIndexPath")
public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
//caused by code
print("SCROLL scrollViewDidEndScrollingAnimation")
}
Notes:
- Put these functions in your UIScrollViewDelegate or UICollectionViewDelegate delegate.
- if you don't have a separate delegate, make your current class extend a UIScrollViewDelegate op top of your class file
.
open class MyClass: NSObject , UICollectionViewDelegate
and somewhere in your viewWillAppear make the class its own delegate
override open func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// ...
self.myScrollView.delegate = self
// ...
}
回答6:
if you want to use the visible indexpath:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self scrollingFinish];
}
- (void)scrollingFinish {
if([self.collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader]){
NSIndexPath *firstVisibleIndexPath = [[self.collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader] firstObject];
[self.collectionView scrollToItemAtIndexPath:firstVisibleIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
}
来源:https://stackoverflow.com/questions/14868269/uicollectionview-how-to-detect-when-scrolling-has-stopped