switch page control activity iphone cocoa-touch uiscrollview

iphone - page - Fotos de la brecha similar a una aplicación entre páginas en UIScrollView con pagingEnabled



switch ios (8)

UIScrollView en modo de paginación asume que las páginas están ubicadas una al lado de la otra, sin espacio. Sin embargo, si abres una foto en la aplicación Fotos y pasas las fotos, puedes ver que hay un espacio entre las páginas. Yo también quiero estos huecos.

Estoy buscando soluciones existentes, si las hay, o algunas ideas más extrañas sobre la implementación de espacios en las páginas, además de la que he explicado a continuación. ¿O tal vez hay alguna forma obvia y fácil de extrañar?

Para que quede claro: quiero que la brecha solo sea visible durante el desplazamiento, por lo que no puedo simplemente insertar el contenido de la página.

Mi plan es intentar mover el contenido de la página desde dentro de la scrollViewDidScroll llamada scrollViewDidScroll , de modo que (suponiendo que se está desplazando hacia la derecha) inicialmente la página de destino esté ligeramente desviada a la derecha de los límites de la página, y en el momento en que llegue al destino la página está de vuelta en su ubicación correcta, y la página de origen está ligeramente desplazada a la izquierda de sus límites. (O tal vez en lugar de mover las cosas continuamente, sería mejor cambiar las compensaciones, por ejemplo, exactamente a mitad de camino entre las páginas).

Soy el autor del artículo + ejemplo de ScrollingMadness al que he estado refiriendo a algunas personas aquí. He implementado el zoom progresivo y obtuve el zoom y el desplazamiento en la foto trabajando conjuntamente con la paginación entre fotografías. Así que sé cómo jugar con UIScrollView, y estoy buscando cosas avanzadas.

Por favor, no me apuntes a TTScrollView. Yo mismo ya lo he señalado a muchas personas, pero considero que se siente demasiado lejos del comportamiento nativo de UIScrollView y no quiero usarlo en mis proyectos.


Tenga en cuenta que esta respuesta es bastante antigua. El concepto básico aún funciona, pero no debe ser difícil modificar el tamaño de las vistas en iOS7 y 8. Incluso si ignora ese consejo, no debe usar 480 o 330.

¿Ha intentado hacer que el marco del UIScrollView poco más grande que la pantalla (suponiendo que desea visualizar sus imágenes en pantalla completa y luego organice sus subvistas en los mismos límites ligeramente más grandes que la pantalla?

#define kViewFrameWidth 330; // i.e. more than 320 CGRect scrollFrame; scrollFrame.origin.x = 0; scrollFrame.origin.y = 0; scrollFrame.size.width = kViewFrameWidth; scrollFrame.size.height = 480; UIScrollView* myScrollView = [[UIScrollView alloc] initWithFrame:scrollFrame]; myScrollView.bounces = YES; myScrollView.pagingEnabled = YES; myScrollView.backgroundColor = [UIColor redColor]; UIImage* leftImage = [UIImage imageNamed:@"ScrollTestImageL.png"]; UIImageView* leftView = [[UIImageView alloc] initWithImage:leftImage]; leftView.backgroundColor = [UIColor whiteColor]; leftView.frame = CGRectMake(0,0,320,480); UIImage* rightImage = [UIImage imageNamed:@"ScrollTestImageR.png"]; UIImageView* rightView = [[UIImageView alloc] initWithImage:rightImage]; rightView.backgroundColor = [UIColor blackColor]; rightView.frame = CGRectMake(kViewFrameWidth * 2,0,320,480); UIImage* centerImage = [UIImage imageNamed:@"ScrollTestImageC.png"]; UIImageView* centerView = [[UIImageView alloc] initWithImage:centerImage]; centerView.backgroundColor = [UIColor grayColor]; centerView.frame = CGRectMake(kViewFrameWidth,0,320,480); [myScrollView addSubview:leftView]; [myScrollView addSubview:rightView]; [myScrollView addSubview:centerView]; [myScrollView setContentSize:CGSizeMake(kViewFrameWidth * 3, 480)]; [myScrollView setContentOffset:CGPointMake(kViewFrameWidth, 0)]; [leftView release]; [rightView release]; [centerView release];

Disculpas si esto no se compila, lo probé en una aplicación de paisaje y lo edité de forma manual. Aunque estoy seguro de que tienes la idea. Se basa en el recorte de supervisión que para una vista de pantalla completa siempre será el caso.


¿Quizás quieras probar la propiedad contentInset de UIScrollView?

myScrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 10.0);


Apple ha lanzado los videos de la sesión WWDC 2010 a todos los miembros del programa de desarrolladores de iPhone. Uno de los temas tratados es cómo crearon la aplicación de fotos. Construyen una aplicación muy similar paso a paso y hacen que todo el código esté disponible de forma gratuita.

Tampoco usa api privado. Aquí hay un enlace a la descarga del código de muestra. Probablemente necesitará iniciar sesión para obtener acceso.

http://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?code=y&source=x&bundleID=20645

Y, aquí hay un enlace a la página de la WWDC de iTunes:

http://insideapple.apple.com/redir/cbx-cgi.do?v=2&la=en&lc=&a=kGSol9sgPHP%2BtlWtLp%2BEP%2FnxnZarjWJglPBZRHd3oDbACudP51JNGS8KlsFgxZto9X%2BTsnqSbeUSWX0doe%2Fzv%2FN5XV55%2FomsyfRgFBysOnIVggO%2Fn2p%2BiweDK%2F%2FmsIXj


Así que no tengo suficiente "representante" para publicar un comentario en la respuesta anterior. Esa respuesta es correcta, pero hay un GRAN problema a tener en cuenta:

Si está utilizando un UIScrollView en un viewController que forma parte de un UINavigationController, el controlador de navegación cambiará el tamaño del marco de su scrollView.

Es decir, tiene una aplicación que utiliza un controlador de control de UIN para cambiar entre diferentes vistas. Presiona un viewController que tiene un scrollView y crea este scrollView en el método viewintroller''s -init. Le asigna un marco de (0, 0, 340, 480).

Ahora, vaya a su método viewviewer-viewDidAppear de viewController, obtenga el marco del scrollView que creó. Encontrarás que el ancho se ha reducido a 320 píxeles. Como tal, la paginación no funcionará correctamente. Usted esperará que el scrollView se mueva 340 píxeles pero, en cambio, se moverá 320.

UINavigationController es un poco conocido por jugar con subvistas. Los mueve y los redimensiona para acomodar la barra de navegación. En resumen, no es un jugador de equipo, especialmente en este caso. Otros lugares en la web sugieren que no utilice UINavigationController si necesita un control preciso sobre el tamaño y las ubicaciones de sus vistas. Sugieren que, en cambio, cree su propia clase de navigationController basada en UINavigationBar.

Bueno, eso es un montón de trabajo. Afortunadamente, hay una solución más sencilla: establezca el marco de scrollView en su método viewviewer-viewDidAppear. En este punto, UINavigationController ha terminado de jugar con el marco, por lo que puede restablecerlo a lo que debería ser y scrollView se comportará correctamente.

Esto es relevante para OS 3.0. No he probado 3.1 o 2.2.1. También presenté un informe de errores con Apple sugiriendo que modifiquen UINavigationController con un BOOL como "-shouldAutoarrangeSubviews" para que podamos hacer que esa clase mantenga sus manos sucias fuera de las subvistas.

Hasta que eso ocurra, la solución anterior le dará espacios en un UIScrollView dentro de un UINavigationController.


Esto es solo una corazonada, así que pido disculpas si está completamente equivocado, pero ¿es posible que contentSize esté configurado ligeramente más ancho que el ancho de la pantalla?

La información correcta se procesa dentro de la vista al ancho de la pantalla y UIScrollView se encarga del resto.


La forma de hacerlo es como usted dijo, una combinación de algunas cosas.

Si desea un espacio de 20px entre sus imágenes, necesita:

Primero, expanda el ancho total de la vista de desplazamiento en 20 px y muévalo hacia la izquierda en 10 px.

En segundo lugar, cuando disponga el xLoc de sus imágenes, agregue 20px para cada imagen para que estén separadas 20px. Tercero, establezca el xLoc inicial de sus imágenes a 10px en lugar de 0px.

Cuarto, asegúrese de configurar el tamaño del contenido de su vista de desplazamiento para agregar 20px para cada imagen. Entonces, si tienes imágenes de kNumImages y cada una es kScrollObjWidth, entonces haz lo siguiente:

[scrollView setContentSize:CGSizeMake((kNumImages * (kScrollObjWidth+20)), kScrollObjHeight)];

¡Después de eso debería de funcionar!


Para evitar meterse con el marco de UIScrollView, puede subclasificar UIScrollView y anular las vistas de diseño para aplicar un desplazamiento a cada página.

La idea se basa en las siguientes observaciones:

  1. Cuando zoomScale! = 1, el desplazamiento es cero cuando está en el borde izquierdo / derecho
  2. Cuando zoomScale == 1, el desplazamiento es cero cuando se encuentra en el centro recto visible

Entonces se deriva el siguiente código:

- (void) layoutSubviews { [super layoutSubviews]; // Find a reference point to calculate the offset: CGRect bounds = self.bounds; CGFloat pageGap = 8.f; CGSize pageSize = bounds.size; CGFloat pageWidth = pageSize.width; CGFloat halfPageWidth = pageWidth / 2.f; CGFloat scale = self.zoomScale; CGRect visibleRect = CGRectMake(bounds.origin.x / scale, bounds.origin.y / scale, bounds.size.width / scale, bounds.size.height / scale); CGFloat totalWidth = [self contentSize].width / scale; CGFloat scrollWidth = totalWidth - visibleRect.size.width; CGFloat scrollX = CGRectGetMidX(visibleRect) - visibleRect.size.width / 2.f; CGFloat scrollPercentage = scrollX / scrollWidth; CGFloat referencePoint = (totalWidth - pageWidth) * scrollPercentage + halfPageWidth; // (use your own way to get all visible pages, each page is assumed to be inside a common container) NSArray * visiblePages = [self visiblePages]; // Layout each visible page: for (UIView * view in visiblePages) { NSInteger pageIndex = [self pageIndexForView:view]; // (use your own way to get the page index) // make a gap between pages CGFloat actualPageCenter = pageWidth * pageIndex + halfPageWidth; CGFloat distanceFromRefPoint = actualPageCenter - referencePoint; CGFloat numOfPageFromRefPoint = distanceFromRefPoint / pageWidth; CGFloat offset = numOfPageFromRefPoint * pageGap; CGFloat pageLeft = actualPageCenter - halfPageWidth + offset; view.frame = CGRectMake(pageLeft, 0.f, pageSize.width, pageSize.height); } }


Simplemente pensé que agregaría aquí para la posteridad la solución con la que terminé yendo. Durante mucho tiempo he estado usando la solución de Bryan para ajustar el marco en -viewDidAppear , y esto ha funcionado de manera brillante. Sin embargo, desde que iOS introdujo la multitarea, me he estado topando con un problema en el que el marco de la vista de desplazamiento cambia cuando la aplicación se reanuda desde el fondo. En este caso, no se llamó a -viewDidAppear y no pude encontrar un método de delegado que se llamaría en el momento adecuado para revertir el cambio. Así que decidí hacer de mi vista de desplazamiento una subvista de la vista de mi Controlador de vista, y esto pareció solucionar el problema. Esto también tiene la ventaja de no tener que usar -viewDidAppear para cambiar el marco, puede hacerlo justo después de crear la vista de desplazamiento. Mi pregunta here tiene los detalles, pero los publicaré aquí también:

CGRect frame = CGRectMake(0, 0, 320, 460); scrollView = [[UIScrollView alloc] initWithFrame:frame]; // I do some things with frame here CGRect f = scrollView.frame; f.size.width += PADDING; // PADDING is defined as 20 elsewhere scrollView.frame = f; [self.view addSubview:scrollView];