Есть ли способ обнаружить или получить уведомление, когда пользователь меняет страницу в UIScrollView с поддержкой пейджинга?
Обнаружение изменения страницы UIScrollView
Ответ 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
}
}
}