Подтвердить что ты не робот

Обнаружение изменения страницы UIScrollView

Есть ли способ обнаружить или получить уведомление, когда пользователь меняет страницу в UIScrollView с поддержкой пейджинга?

4b9b3361

Ответ 1

Реализовать делегат UIScrollView. Этот метод - это то, что вы ищете.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

Ответ 2

Используйте это, чтобы определить, какая страница отображается в данный момент, и выполните некоторые действия при изменении страницы:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    static NSInteger previousPage = 0;
    CGFloat pageWidth = scrollView.frame.size.width;
    float fractionalPage = scrollView.contentOffset.x / pageWidth;
    NSInteger page = lround(fractionalPage);
    if (previousPage != page) {
        // Page has changed, do your thing!
        // ...
        // Finally, update previous page
        previousPage = page;
    }
}

Если вам удастся отреагировать только на изменение страницы после полной остановки прокрутки, лучше всего сделать это в методе делегата scrollViewDidEndDecelerating: вместо метода scrollViewDidScroll:.

Ответ 3

В режиме прокрутки с поддержкой пейджинга вы можете использовать scrollViewDidEndDecelerating, чтобы узнать, когда представление будет разрешено на странице (может быть, одна и та же страница),

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

scrollViewDidScroll вызывается при каждом движении. И в контексте просмотра пейджинга можно использовать, чтобы найти, когда он прокручивается достаточно, чтобы перейти на следующую страницу (если перетаскивание остановлено в этой точке).

Ответ 4

Как насчет объединения двух методов UIScrollViewDelegate?

В scrollViewDidEndDragging(_:willDecelerate:), если он сразу останавливается, мы делаем расчет страницы; если он замедляется, мы отпускаем его, и он будет пойман scrollViewDidEndDecelerating(_:).

Код тестируется с XCode версии 7.1.1, Swift версии 2.1

class ViewController: UIViewController, UIScrollViewDelegate {

  // MARK: UIScrollViewDelegate
  func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if decelerate == false {
        let currentPage = scrollView.currentPage
        // Do something with your page update
        print("scrollViewDidEndDragging: \(currentPage)")
    }
  }

  func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    let currentPage = scrollView.currentPage
    // Do something with your page update
    print("scrollViewDidEndDecelerating: \(currentPage)")
  }

}

extension UIScrollView {
   var currentPage: Int {
      return Int((self.contentOffset.x+ (0.5*self.frame.size.width))/self.frame.width)+1
   }
}

Ответ 5

Первый результат в google для обнаружения страницы, поэтому я должен был ответить на это с лучшим решением, на мой взгляд. (даже если этот вопрос задавали два с половиной года назад.)

Я бы предпочел не называть scrollViewDidScroll только для отслеживания номера страницы. Thats overkill для чего-то простого. Использование scrollViewDidEndDecelerating работает и останавливается при изменении страницы НО (и это большой, но), если пользователь будет прокручивать на экране в два раза быстрее, чем обычно, scrollViewDidEndDecelerating будет вызываться только один раз. Вы можете легко перейти со страницы № 1 на страницу № 3 без обработки страницы № 2.

Это полностью решило для меня:

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
    scrollView.userInteractionEnabled = NO;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    //Run your code on the current page
    scrollView.userInteractionEnabled = YES;
}

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

Ответ 6

Вот быстрое решение для этого.

Создайте два свойства currentPage и previousPage в классе, в котором вы реализуете свой код, и инициализируете их до 0.

Теперь обновите currentPage из scrollViewDidEndDragging (: willDecelerate:) и scrollViewDidEndDecelerating (: scrollView:).

И затем обновите предыдущую страницу в scrollViewDidEndScrollingAnimation (_: scrollView:)

    //Class Properties
    var currentPage = 0
    var previousPage = 0

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        updatePage(scrollView)
        return
    }

 func scrollViewDidEndDecelerating(scrollView: UIScrollView){
        updatePage(scrollView)
        return
    }


 func updatePage(scrollView: UIScrollView) {
        let pageWidth:CGFloat = scrollView.frame.width
        let current:CGFloat = floor((scrollView.contentOffset.x-pageWidth/2)/pageWidth)+1
        currentPage = Int(current)

        if currentPage == 0 {
              // DO SOMETHING
        }
        else if currentPage == 1{
              // DO SOMETHING

        }
    }

func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {
     if previousPage != currentPage {
          previousPage = currentPage
          if currentPage == 0 {
              //DO SOMETHING
             }else if currentPage == 1 {
               // DO SOMETHING
           }
       }
   }