2010-11-09 2 views
83

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

Это скрыто от нас полностью или есть способ получить к нему доступ?

ответ

237

Для текущей страницы нет UIScrollView. Вы можете вычислить его с:

int page = scrollView.contentOffset.x/scrollView.frame.size.width; 

Если вы хотите, чтобы округлить вверх или вниз до ближайшей страницы, используйте:

CGFloat width = scrollView.frame.size.width; 
NSInteger page = (scrollView.contentOffset.x + (0.5f * width))/width; 
+37

Действительно, похоже, как оплошности со стороны компании Apple ... – elsurudo

+7

Не забудьте использовать 'UIScrollViewDelegate', чтобы получить текущую страницу, когда пользователь прокручивает! –

+0

Это может иметь проблемы при работе с вращением. –

1

Вы используете UIPageControl? Если это так, у этого объекта есть свойство currentPage. Если нет, я думаю, вам нужно будет вычислить индекс страницы из смещения scrollView.

6

Просто разделить текущее смещение по размеру страницы:

CGFloat pageNum = (int)(scrollView.contentOffset.x/scrollView.frame.size.width); 
+10

Кастинг для int, а затем присвоение поплавка? Почему бы не сделать pageNum int также;) – Klaas

3

Решение Aoakenfo удивительно, это еще одно решение, сочетающее ваш код с функцией scrollViewDidScroll и PageController

- (void)scrollViewDidScroll:(UIScrollView *)sender { 
    if (sender == self.scroll) { 
     int pageNum = (int)(self.scrPage.contentOffset.x/self.scrPage.frame.size.width); 
     self.pagecontroller.currentPage =pageNum; 
    } 
} 
+0

Это жадный, не ленивый ... Это также не MVC. Более простой способ - аннулировать текущую страницу в прокрутке и установить ее только тогда, когда она запрошена ... все из подкласса или категории в UIScrollView – Barry

12

Как указано выше, но как категория


@interface UIScrollView (CurrentPage) 
-(int) currentPage; 
@end 
@implementation UIScrollView (CurrentPage) 
-(int) currentPage{ 
    CGFloat pageWidth = self.frame.size.width; 
    return floor((self.contentOffset.x - pageWidth/2)/pageWidth) + 1; 
} 
@end 
+6

Это перебор, просто используйте return round (self.contentOffset.x/self.frame.size .ширина); Гораздо проще и проще понять .. –

+0

-1 @LeonardPauli. Вышеприведенная реализация возвращает страницу с видимостью более 50%.Наивная реализация изменяет только значение страницы, когда subview прокрутки занимает все границы прокрутки. – user

+1

@user Во-первых, пол() раундов всегда вниз, а round() округляется, если десятичная часть> 5, иначе вниз. При этом слово (a) = round (a-0,5). Давайте сделаем простую алгебру. (a/b-0.5) 1.5 = 1 раунд (a/b-0.5) +1 = раунд (a/b-1) +1 = раунд (a/b-0.5) а/б). Смотри! Кажется, что пол ((a-b/2)/b) +1 = round (a/b)! Mathemagical. –

2

Я извлек это из нескольких наших приложений ...

- (NSInteger)currentPage 
{ 
    if (0 == self.frame.size.width) { 
     NSLog(@"frame width == 0!"); 
     return 0; 
    } 
    if (! self.currentPageValid) { 
     _currentPage = round(self.contentOffset.x/self.frame.size.width); 
     self.currentPageValid = YES; 
    } 
    return _currentPage; 
} 

Full source here

26

Я очень рекомендую вам используйте этот код

int indexOfPage = scrollView.contentOffset.x/scrollView.frame.size.width; 

, но если вы используете этот код, ваше представление не обязательно должно быть точно на странице, которую дает indexOfPage. Это потому, что я также рекомендую использовать этот код только в этом методе

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{} 

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

Я рекомендую вам установить Scrollview к выгружаемому включено с этим кодом

[scrollView setPagingEnabled:YES]; 

Так, наконец, он должен выглядеть таким образом

-(void) methodWhereYouSetYourScrollView 
{ 
    //set scrollView 
    [scrollView setPagingEnabled:YES]; 
    scrollView.delegate = self; 
} 

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{ 
    int indexOfPage = scrollView.contentOffset.x/scrollView.frame.size.width; 
    //your stuff with index 
} 
+0

Спасибо .. я просто искал ..! –

+0

Я проверил каждый ответ, но он отлично работает для меня ... спасибо человеку .. – g212gs

+0

не работает на устройстве iOS7 (скомпилировано с XCODE 6.2) contentOffset.x равно 639 вместо 640 (не спрашивайте меня, почему ...), когда scrollViewDndEndDecelerating. user363349 ответ правильный: пол возврата ((self.contentOffset.x - pageWidth/2)/pageWidth) + 1; – Vassily

21

В стрижа я хотел бы сделать это в расширении:

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

Тогда просто позвоните:

scrollView.currentPage 
+4

Почти идеальный, мне пришлось удалить +1 в конце, потому что все в моем мире равно нулю – mvandillen

6

Там некоторые хорошие ответы уже здесь.Тем не менее, для сценариев, где контент не соответствует точно на странице, - и, как и я, вы хотите использовать результат для UIPageControl, тогда важно использовать функцию ceil.

Давайте рассмотрим пример, где у меня есть «четыре и несколько» страниц содержимого.

Я опишу это на примере моей настоящей реальной жизни. Ширина содержимого составляет 3140 точек. Основываясь на мой взгляд, коллекция размер кадра, ширина страницы 728.

Так количество страниц равно:

3140/728 = 4.313 

Мой numberOfPages будет пять. Четыре из которых будут отображаться полностью, а последняя из которых - стр. Пять - покажет, что осталось 0.313 контента.

Теперь numberOfPages быть пяти означает, что индексы страницы будут 0, 1, 2, 3 и 4.

Когда я проведите вправо, поисковый вызов к конечному смещению, метод scrollViewDidEndDecelerating дают окончательное смещение X из 2412.

Применение скругления расчет:

2412/728 = 3.313 then rounded = 3 

Это неправильно. пользователь просматривает страницу на смещение должно быть:

Offset/Page User Is Viewing 
0  0 
728  1 
1456  2 
2184  3 
2412  4 

Правильный расчет с использованием ceil:

private func pageForOffset(offset:CGFloat, pageWidth width:CGFloat) -> Int 
{ 
    let page = Int(ceil(offset/width)) 
    NSLog("\(__FUNCTION__) offset \(offset) width \(width) page \(page) ") 
    return page 
} 
+1

Это отличный ответ. Спасибо, что нашли время, чтобы написать подробное объяснение, почему оно работает. – TigerCoding

3

В Xcode 7.x быстрой 2.x вы можете сделать:

//MARK: - ScrollView Extensions 
// Get the current page number 
extension UIScrollView { 
    var currentPage: Int { 
     return Int(round(self.contentOffset.x/self.bounds.size.width)) 
    } 

// If you have reversed offset (start from contentSize.width to 0) 
    var reverseCurrentPage: Int { 
     return Int(round((contentSize.width - self.contentOffset.x)/self.bounds.size.width))-1 
    } 
} 
2

Для быстрых я бы просто использовал это

let width = scrollView.frame.width 
    let page = round(scrollView.contentOffset.x/width) 

Довольно просто, он в основном занимает положение прокрутки в виде x, делит его на ширину прокрутки, а затем округляет его.

0

Другой способ:

extension MyViewController: UIScrollViewDelegate { 
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 
     let width = scrollView.frame.width 
     let page = Int(round(scrollView.contentOffset.x/width)) 
     print("CurrentPage:\(page)") 
    } 
} 
Смежные вопросы