it-roy-ru.com

UICollectionView: как определить, когда прокрутка остановилась

Я использую UICollectionView для быстрой прокрутки набора миниатюр. Как только прокрутка закончится, я бы хотел показать увеличенную версию текущего эскиза в высоком разрешении. 

Как я могу определить, когда пользователь завершил прокрутку? Я реализую didEndDisplayingCell, но это говорит мне только о том, когда конкретная ячейка прокручивается; это не говорит мне, когда движение прокрутки фактически завершается.

51
George Armhold
NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView

UICollectionView является подклассом UIScrollView. Поэтому, если вы установили делегат и внедрили UIScrollViewDelegate, вы сможете обнаружить это так же, как UIScrollView.

Например: 

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;

Согласно документации , вышеупомянутый метод должен сказать, когда представление прокрутки прекратило замедлять движение прокрутки.

112
iDev

Просто для покрытия ваших баз вы должны реализовать оба этих метода UIScrollViewDelegate . В некоторых случаях может не быть замедления (и scrollViewDidEndDecelerating не будет вызываться), например, страница полностью прокручивается на месте. В этом случае сделайте свое обновление прямо здесь в scrollViewDidEndDragging.

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
  if (!decelerate) {
    [self updateStuff];
  }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
  [self updateStuff];
}
51
Abey M

Важный факт, чтобы отметить здесь: 

Этот метод вызывается на инициируемых пользователем свитках (т. Е. Жестом панорамирования)

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;

С другой стороны, этот вызывается на всех вручную (программно) инициируемых свитках (например, scrollRectToVisible или scrollToItemAtIndexPath)

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
30
D6mi

Версия Swift 3:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    // Your code here
}
8
Mr Stanev

Swift 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 op top вашего файла класса

,.

open class MyClass: NSObject , UICollectionViewDelegate

и где-то в вашем viewWillAppear сделать класс своим собственным делегатом

override open func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // ...
    self.myScrollView.delegate = self
    // ...
}
4
drpawelo

если вы хотите использовать видимый путь индекса:

- (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];
    }
}
0
Ofir Malachi