2010-11-09 15 views
83

W moim widoku przewijania chcę wyświetlić bieżącą stronę, która jest wyświetlana (może strona nie jest poprawnym terminem). Nie mogę znaleźć żadnej zmiennej, która to posiada. Ale myślę, że to musi być gdzieś, ponieważ wskaźnik jest w stanie pokazać, który podmenu widoku przewijania jest aktualnie wyświetlany.Uzyskiwanie bieżącej strony

Czy to ukryta przed nami całkowicie albo czy jest jakiś sposób dla mnie do niego dostęp?

Odpowiedz

237

Nie ma UIScrollView nieruchomość do bieżącej strony. Można go obliczyć z:

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

Jeśli chcesz zaokrąglić w górę lub w dół do najbliższej strony, użyj:

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

naprawdę nie wydaje się niedopatrzenia ze strony Apple'a ... – elsurudo

+7

Nie zapomnij użyć 'UIScrollViewDelegate' uzyskać bieżącej strony, gdy użytkownik przewija! –

+0

Może to powodować problemy podczas obracania. –

1

Używasz UIPageControl? Jeśli tak, to ma właściwość currentPage. Jeśli nie, myślę, że będziesz musiał obliczyć indeks strony z przesunięcia scrollView.

6

Wystarczy podzielić prąd przesunięcia przez rozmiaru strony:

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

Przesyłanie do int, a następnie przypisywanie do float? Dlaczego nie zrobić pageNum int również;) – Klaas

3

Rozwiązanie Aoakenfo jest niesamowite, to kolejne rozwiązanie łączące Twój kod z funkcją scrollViewDidScroll i 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

To jest chciwe, nie leniwe ... To także nie jest MVC. Znacznie prostszym sposobem jest unieważnienie bieżącej strony podczas przewijania i ustawienie jej tylko wtedy, gdy jest wymagana ... wszystko z podklasy lub kategorii na UIScrollView – Barry

12

Jak wyżej, ale jako kategoria


@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

To przesada, po prostu użyj rundy powrotnej (self.contentOffset.x/self.frame.size .szerokość); Znacznie prostsze i łatwiejsze do zrozumienia .. –

+0

-1 @ LeonardPauli. Powyższa implementacja zwraca stronę, która jest widoczna w ponad 50%.Naiwna implementacja zmienia tylko wartość strony, gdy podgląd wyskoku zajmuje całe ograniczenie przewijania. – user

+1

@user Po pierwsze, floor() zaokrągla zawsze w dół, a round() zaokrągla w górę, jeśli część dziesiętna wynosi> = 5, w przeciwnym razie. Mówiąc to, podłoga (a) = okrągła (a-0,5). Zróbmy trochę prostej algebry. podłoga ((ab/2)/b) +1 = podłoga (a/b-0,5) +1 = runda (a/b-0,5-0,5) +1 = runda (a/b-1) +1 = runda (a/b). Popatrz! Wygląda jak podłoga ((a-b/2)/b) +1 = runda (a/b)! Matematyka. –

2

Ja wybiłem to z kilku naszych aplikacji ...

- (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

ja bardzo polecam Ci użyj tego kodu

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

ale jeśli użyjesz tego kodu, Twój widok nie musi znajdować się dokładnie na stronie, którą daje nam IndexOfPage. to, bo ja też zalecamy, aby użyć tego kodu tylko w tej metodzie

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

który nazywa gdy Scrollview zakończy przewijanie i mieć numer swojej strony bardzo ostrym

polecam ustawić Scrollview na pager włączony z tym kodem

[scrollView setPagingEnabled:YES]; 

Więc w końcu powinien wyglądać ten sposób

-(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

Dzięki .. Po prostu szukałem ..! –

+0

Sprawdziłem wszystkie inne odpowiedzi, ale działa to idealnie dla mnie ... dzięki człowiekowi .. – g212gs

+0

nie działa na urządzeniu iOS7 (skompilowanym z XCODE 6.2) contentOffset.x wynosi 639 zamiast 640 (nie pytaj mnie dlaczego ...), gdy scrollViewDidEndDecelerating. user363349 odpowiedź jest poprawna: podłoga powrotu ((self.contentOffset.x - pageWidth/2)/pageWidth) + 1; – Vassily

21

w Swift zrobiłbym to w rozszerzeniu:

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

Następnie wystarczy zadzwonić:

scrollView.currentPage 
+4

Prawie perfekcyjnie, musiałem usunąć +1 na końcu, ponieważ wszystko jest zerowe w moim świecie. – mvandillen

6

Jest kilka dobrych odpowiedzi tutaj już.Jednak w przypadku scenariuszy, w których zawartość nie pasuje dokładnie do strony - i jeśli chcesz, podobnie jak ja, chcesz użyć wyniku dla numeru UIPageControl, konieczne jest użycie funkcji ceil.

Weźmy przykład, w którym mam "cztery i trochę" strony treści.

Opieram to na moim obecnym przykładzie z życia. Szerokość treści wynosi 3140 punktów. Opierając się na moim zdaniem kolekcja rozmiar ramki, szerokość strony to 728.

Więc liczba stron wynosi:

3140/728 = 4.313 

My numberOfPages będzie pięć. Cztery z nich pokażą się w całości, a na końcu - na stronie piątej - pokaże pozostały 0.313 treści.

Teraz numberOfPages jest pięć oznacza, że ​​strona będzie indeksy 0, 1, 2, 3 i 4.

Kiedy przesunąć w prawo, w kierunku stronicowania końcowe przesunięcie metoda scrollViewDidEndDecelerating dało końcowe przesunięcie w od 2412.

Zastosowanie obliczeń zaokrągleń:

2412/728 = 3.313 then rounded = 3 

To błędne. użytkownik przegląda strony przez przesunięcie powinno być:

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

Prawidłowe obliczenie używając 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

To jest świetna odpowiedź. Dziękuję za poświęcenie czasu na napisanie tak szczegółowego wyjaśnienia, dlaczego to działa. – TigerCoding

3

w Xcode 7.x szybkiej 2.x można zrobić:

//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

Dla szybkiego użyłbym tylko tego

Dość proste, w zasadzie przyjmuje pozycję x przewijania, dzieli ją według szerokości przewijania, a następnie ją zaokrągla.

0

Innym sposobem:

extension MyViewController: UIScrollViewDelegate { 
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 
     let width = scrollView.frame.width 
     let page = Int(round(scrollView.contentOffset.x/width)) 
     print("CurrentPage:\(page)") 
    } 
} 
Powiązane problemy