2010-11-09 33 views
83

En mi vista de desplazamiento, quiero obtener la página actual que se muestra (tal vez la página no es el término correcto). No puedo encontrar ninguna variable que contenga esto. Pero creo que debe llevarse a cabo en alguna parte, ya que el indicador puede mostrar qué subvista de la vista de desplazamiento se está mostrando actualmente.Obteniendo la página actual

¿Está oculto por completo o hay alguna forma de acceder?

Respuesta

237

No hay propiedad de UIScrollView para la página actual. Se puede calcular con:

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

Si desea redondear hacia arriba o hacia abajo con una aproximación de la página, utilice:

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

realmente parecen como un descuido por parte de Apple ... – elsurudo

+7

No se olvide de utilizar el 'UIScrollViewDelegate' para obtener la página actual cuando el usuario se desplaza! –

+0

Esto puede tener problemas cuando se trata de rotación. –

1

¿Estás utilizando un UIPageControl? Si es así, esto tiene una propiedad currentPage. De lo contrario, creo que deberá calcular el índice de la página desde el desplazamiento de scrollView.

6

Sólo dividir el desplazamiento por el tamaño de página actual:

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

¿Transmitir a int y luego asignar a un float? ¿Por qué no hacer pageNum int también;) – Klaas

3

La solución de Aoakenfo es increíble, esta es otra solución que combina su código con la función scrollViewDidScroll y 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

Esto es codicioso, no perezoso ... Tampoco es MVC. Una forma mucho más simple es invalidar la página actual en desplazamiento, y configurarla solo cuando se solicite ... todo desde una subclase o categoría en UIScrollView – Barry

12

Como el anterior pero como categoría


@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

Eso es exagerado, solo use return round (self.contentOffset.x/self.frame.size .anchura); Mucho más simple y fácil de entender .. –

+0

-1 @LeonardPauli. La implementación anterior devuelve la página que es más del 50% visible.La implementación ingenua solo cambia el valor de la página cuando la subvista de scrollview ocupa todos los límites de la vista de desplazamiento. – user

+1

@user En primer lugar, floor() redondea siempre hacia abajo, y round() redondea hacia arriba si la parte decimal es> = 5, sino hacia abajo. Dicho esto, piso (a) = redondo (a-0.5). Hagamos algo de álgebra simple. piso ((ab/2)/b) +1 = piso (a/b-0.5) +1 = redondo (a/b-0.5-0.5) +1 = redondo (a/b-1) +1 = redondo (a/b). ¡Mira! Parece que piso ((a-b/2)/b) +1 = redondo (a/b)! Mathemagical. –

2

extraje esto fuera de un par de nuestras aplicaciones ...

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

Ya casi se recomiendan para utilice este código

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

pero si utiliza este código, no es necesario que su vista esté exactamente en la página que le proporciona indexOfPage. Es porque yo también recomiendo que utilice este código sólo en este método

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

que se llama cuando su ScrollView termina el desplazamiento y tener el número de la página realmente fuerte

Te recomiendo que fija su ScrollView a paginado habilitado con este código

[scrollView setPagingEnabled:YES]; 

Así que, finalmente, que debe ser similar esa manera

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

Gracias ... simplemente estaba buscando ...! –

+0

comprobé todas las demás respuestas pero me funcionó a la perfección ... gracias hombre ... – g212gs

+0

no funciona en el dispositivo iOS7 (compilado con XCODE 6.2) contentOffset.x es igual a 639 en lugar de 640 (no me pregunte por qué ...) cuando scrollViewDidEndDecelerating. user363349 la respuesta es correcta: return floor ((self.contentOffset.x - pageWidth/2)/pageWidth) + 1; – Vassily

21

en Swift lo haría en extensión:

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

A continuación, sólo llaman:

scrollView.currentPage 
+4

Casi perfecto, tuve que eliminar el +1 al final ya que todo está basado en cero en mi mundo – mvandillen

6

Hay algunas buenas respuestas aquí ya.Sin embargo, para escenarios donde el contenido no se ajusta exactamente a una página, y si desea utilizar el resultado para un UIPageControl, entonces es esencial usar la función ceil.

Veamos un ejemplo en el que tengo páginas de contenido "cuatro y un poco".

Voy a basar esto en mi ejemplo actual de la vida real. El ancho del tamaño del contenido es 3140 puntos. Con base en mi opinión colección tamaño del marco, ancho de página es 728.

Así número de páginas es igual a:

3140/728 = 4.313 

Mi numberOfPages va a ser cinco. Cuatro de los cuales se mostrarán en su totalidad, y el último de ellos, página cinco, mostrará el contenido restante de 0.313.

Ahora, numberOfPages ser cinco medios que los índices de página será 0, 1, 2, 3, y 4.

Cuando desliza el dedo hacia la derecha, la paginación hacia compensar el final, el método scrollViewDidEndDecelerating da un desplazamiento final de X de 2412.

la aplicación del cálculo de redondeo:

2412/728 = 3.313 then rounded = 3 

Eso es incorrecto. Página usuario está viendo por el desplazamiento debe ser:

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

El cálculo correcto usando 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

Esta es una gran respuesta. Gracias por tomarse el tiempo para escribir una explicación tan detallada de por qué funciona. – TigerCoding

3

En xCode 7.x 2.x rápida que puede hacer:

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

Para swift simplemente usaría esto

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

Bastante sencillo, básicamente toma la posición scrollview x, la divide por el ancho de la vista de desplazamiento y luego la redondea.

0

Otra forma:

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