UICollectionView: как обнаружить, когда прокрутка остановлена
Я использую UICollectionView
для быстрого прокрутки набора эскизов. Как только прокрутка заканчивается, я хотел бы отобразить более крупную версию hi-res текущего миниатюры.
Как определить, когда пользователь завершил прокрутку? Я реализую didEndDisplayingCell
, но это только говорит мне, когда определенная ячейка прокручивается; он не говорит мне, когда движение прокрутки действительно завершается.
Ответы
Ответ 1
NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView
UICollectionView
является подклассом UIScrollView
. Поэтому, если вы установили делегат и внедрили UIScrollViewDelegate
, вы должны обнаружить это так же, как UIScrollView
.
Например: -
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
В соответствии с documentation описанный выше метод должен указывать, когда режим прокрутки закончил замедлять движение прокрутки.
Ответ 2
Чтобы покрыть ваши базы, вы должны реализовать оба этих метода UIScrollViewDelegate.
В некоторых случаях может не произойти замедление (и scrollViewDidEndDecelerating
не будет вызываться), например, страница полностью прокручивается на место. В этом случае сделайте свое обновление прямо в scrollViewDidEndDragging
.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate) {
[self updateStuff];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self updateStuff];
}
Ответ 3
Важный факт, который следует отметить здесь:
Этот метод вызывается для инициированных пользователем свитков (т.е. жестов панорамирования)
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
С другой стороны, этот вызов вызывается во всех запрограммированных вручную запрограммированных свитках (например, "scrollRectToVisible" или "scrollToItemAtIndexPath" )
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
Ответ 4
Версия Swift 3:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Your code here
}
Ответ 5
если вы хотите использовать видимый индексный путь:
- (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];
}
}
Ответ 6
Свифт 3 версии Abey M и D6mi отвечает:
Когда прокрутка вызвана действием пользователя
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")
}
Примечания:
- Поместите эти функции в делегат UIScrollViewDelegate или UICollectionViewDelegate.
- Если у вас нет отдельного делегата, сделайте свой текущий класс расширением UIScrollViewDelegate поверх вашего файла класса
.
open class MyClass: NSObject , UICollectionViewDelegate
и где-то в вашем представленииWillAppear делает класс своим делегатом
override open func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// ...
self.myScrollView.delegate = self
// ...
}