我正在使用一个 UICollectionView
来快速浏览一组缩略图。当滚动结束后,我想显示当前缩略图的更大分辨率版本。
如何检测用户何时完成滚动?我确实实现了 didEndDisplayingCell
,但这只告诉我特定单元格已经滚动出去了;它并没有告诉我滚动操作实际上何时完成。
我正在使用一个 UICollectionView
来快速浏览一组缩略图。当滚动结束后,我想显示当前缩略图的更大分辨率版本。
如何检测用户何时完成滚动?我确实实现了 didEndDisplayingCell
,但这只告诉我特定单元格已经滚动出去了;它并没有告诉我滚动操作实际上何时完成。
NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView
UICollectionView
是UIScrollView
的子类。因此,如果您已设置委托并实现了UIScrollViewDelegate
,则应该能够以与UIScrollView
相同的方式检测到它。
例如:
Objective-C:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
Swift:
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView)
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
scrollViewDidEndDecelerating
在某些情况下可能不会被调用。为了防患未然,您应该实现这两个 UIScrollViewDelegate 方法。在某些情况下,可能不会有减速(并且 scrollViewDidEndDecelerating
不会被调用),例如,页面完全滚动到位的情况。在这种情况下,请直接在 scrollViewDidEndDragging
中进行更新。
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate) {
[self updateStuff];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self updateStuff];
}
scrollViewDidEndDecelerating
不会被调用,而是调用了scrollViewDidEndDragging
。感谢您发布这个答案。 - John Erck需要注意的重要事实。
该方法在用户发起滚动(即平移手势)时调用:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
或者在Swift中:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
另一方面,这个方法在所有手动(编程方式)发起的滚动上被调用(如scrollRectToVisible
或scrollToItemAtIndexPath
):
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
或者在Swift中:
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView)
Abey M和D6mi的答案的Swift 3版本:
当滚动是由用户操作引起时
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")
}
当滚动是由代码动作(编程方式)引起时:(例如“scrollRectToVisible”或“scrollToItemAtIndexPath”)
public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
//caused by code
print("SCROLL scrollViewDidEndScrollingAnimation")
}
备注:
.
备注:
.
open class MyClass: NSObject , UICollectionViewDelegate
在您的viewWillAppear中,让该类成为其自己的代理
override open func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// ...
self.myScrollView.delegate = self
// ...
}
Swift 3版本:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Your code here
}
如果你想使用可见的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];
}
}
UIScrollViewDelegate
。public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let xPoint = scrollView.contentOffset.x + scrollView.frame.width / 2
let yPoint = scrollView.frame.height / 2
let center = CGPoint(x: xPoint, y: yPoint)
if let ip = self.collectionView.indexPathForItem(at: center) {
pageIndex = ip.row
}
print(">>>>>>>>>\(pageIndex)")
}
scrollViewDidEndDecelerating
没有被调用,但像D6mi所说,scrollViewDidEndScrollingAnimation
被调用了。 - AkademiksQc