En este tutorial vamos a crear un slider. Este slider nos va a permitir arrastrar para cambiar la página del scroll y conocer la página a la que navegaremos según su posición.
En primer lugar necesitaremos crear un nuevo proyecto. En este caso, nos bastará con emplear el tipo Single View Application.
Además, bloqueamos la orientación de forma que sólo podamos utilizarla en horizontal o landscape.
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);}>/code>
Ahora vamos a preparar la interfaz. Para ello necesitamos crear los botones y la barra inferior.
El código que emplearemos para este gesto será el siguiente:
(void)panHandler:(UIPanGestureRecognizer *)sender {switch (sender.state) {case UIGestureRecognizerStateBegan: {// Obtenemos el frame inicialinitialFrame = sender.view.frame;// Obtenemos el movimiento del sliderCGPoint translation = [sender translationInView:sender.view.superview];// Ajustamos el frame y lo asignamos al sliderCGRect newFrame = initialFrame;newFrame.origin.x += translation.x;sender.view.frame = newFrame;break;}case UIGestureRecognizerStateChanged: {// Obtenemos el movimiento del sliderCGPoint translation = [sender translationInView:sender.view.superview];// Ajustamos la posiciónCGRect newFrame = initialFrame;newFrame.origin.x += translation.x;// Comprobamos que no desplazamos el slider fuera de los límitesif (newFrame.origin.x < 40) {newFrame.origin.x = 40;}if (newFrame.origin.x + newFrame.size.width > 440) {newFrame.origin.x = 440 - newFrame.size.width;}// Asignamos el nuevo framesender.view.frame = newFrame;break;}case UIGestureRecognizerStateEnded: {break;}default:break;}}
Ahora vamos a añadir un UIScrollView con la propiedad Paging Enabled activada, y ocultamos los scrollers horizontal y vertical.
Vamos a añadir unos cuantos elementos a dicho scroll. Podemos usar el siguiente código en el método viewDidLoad:
// Creamos labels para añadir contenido a nuestro scrollfor (int i=0; i&lt;PAGES; i++) {// Cada label tendrá el ancho y la altura del scroll para ocupar todo el espacioUILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(i*scrollView.frame.size.width, 0, scrollView.frame.size.width, scrollView.frame.size.height)];// Texto de color negro, centrado y color de fondo trasparentelabel.textColor = [UIColor blackColor];label.textAlignment = NSTextAlignmentCenter;label.backgroundColor = [UIColor clearColor];label.font = [UIFont fontWithName:@"Helvetica" size:34];// Añadimos el texto al labellabel.text = [NSString stringWithFormat:@"%d", i+1];// Añadimos el label al scroll[scrollView addSubview:label];}// Ajustamos el tamaño del contenido del scroll de forma que sea su ancho por cada página que hemos creadoscrollView.contentSize = CGSizeMake(PAGES*scrollView.frame.size.width, scrollView.contentSize.height);
Una vez tenemos el scroll y el slider no queda más que enlazarlos. Primero vamos a hacer que el slider se mueva al desplazar el scroll. Para ello necesitaremos indicar que nuestro UIViewController es el delegate del scroll. Podemos realizar esto tanto por código como por el storyboard.
Una vez asignado el delegate empleamos el método scrollViewDidEndDecelerating: para ajustar el slider:
// Calculamos el ancho de una página del scrollCGFloat pageWidth = scrollView.frame.size.width;// Calculamos la página en la que nos encontramosfloat page = floor((aScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;// Ajustamos el frame para el sliderCGRect newFrame = self.btnSlider.frame;newFrame.origin.x = 40 + (page) * 400/(PAGES +1);// Realizamos la animación para el desplazamiento del slider[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionAllowUserInteractionanimations:^{self.btnSlider.frame = newFrame;} completion:nil];
Ahora únicamente queda realizar el efecto contrario, mover el slider y desplazar el scroll a su posición correspondiente. Para conseguir este efecto, tendremos que modificar el método panHandler: para añadir el código siguiente en el case correspondiente al fin del gesto, UIGestureRecognizerStateEnded.
case UIGestureRecognizerStateEnded: {// Obtenemos la página del scroll y lo desplazamos acorde al movimiento del sliderfloat page = sender.view.frame.origin.x / (400 / PAGES) - 1;// Si la página es inferior a 1 debemos ir a la primera, es decir, la página 0if (page < 1)page = 0;page = roundf(page);// Desplazamos el scroll a la posición correspondiente[scrollView setContentOffset:CGPointMake(page*scrollView.frame.size.width, scrollView.contentOffset.y) animated:YES];break;}
Por último, vamos a añadir un elemento extra, que nos permitirá saber a qué elemento iremos si soltamos el slider en una posición determinada. Para ello, añadimos un objeto UILabel a nuestra interfaz, centramos su texto y lo ocultamos mediante la propiedad alpha.
A continuación sólo queda mostrar el UILabel al iniciar el UIPanGestureRecognizer, cambiar el nombre conforme se desplace y volver a ocultarlo al soltar el slider:
(void)panHandler:(UIPanGestureRecognizer *)sender {switch (sender.state) {case UIGestureRecognizerStateBegan: {// Obtenemos el frame inicialinitialFrame = sender.view.frame;// Obtenemos el movimiento del sliderCGPoint translation = [sender translationInView:sender.view.superview];// Ajustamos el frame y lo asignamos al sliderCGRect newFrame = initialFrame;newFrame.origin.x += translation.x;sender.view.frame = newFrame;
// Mostramos el label con el título de las páginas[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionAllowUserInteractionanimations:^{self.pageTitle.alpha = 1.0;} completion:nil];break;}case UIGestureRecognizerStateChanged: {// Obtenemos el movimiento del sliderCGPoint translation = [sender translationInView:sender.view.superview];// Ajustamos la posiciónCGRect newFrame = initialFrame;newFrame.origin.x += translation.x;// Comprobamos que no desplazamos el slider fuera de los límitesif (newFrame.origin.x < 40) {newFrame.origin.x = 40;}if (newFrame.origin.x + newFrame.size.width > 440) {newFrame.origin.x = 440 - newFrame.size.width;}// Asignamos el nuevo framesender.view.frame = newFrame;
// Calculamos la página a la que iríamos en caso de soltar el sliderfloat page = sender.view.frame.origin.x / (400 / PAGES) - 1;// Si la página es inferior a 1 debemos ir a la primera, es decir, la página 0if (page < 1)page = 0;page = roundf(page);// Asignamos el texto correspondiente al labelself.pageTitle.text = [NSString stringWithFormat:@"%d", (int)page+1];break;}case UIGestureRecognizerStateEnded: {// Obtenemos la página del scroll y lo desplazamos acorde al movimiento del sliderfloat page = sender.view.frame.origin.x / (400 / PAGES) - 1;// Si la página es inferior a 1 debemos ir a la primera, es decir, la página 0if (page < 1)page = 0;page = roundf(page);// Desplazamos el scroll a la posición correspondiente[scrollView setContentOffset:CGPointMake(page*scrollView.frame.size.width, scrollView.contentOffset.y) animated:YES];
// Al soltar, ocultamos de nuevo el label[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionAllowUserInteractionanimations:^{self.pageTitle.alpha = 0.0;} completion:nil];break;}default:break;}}
Con estos pasos ya tendríamos preparado el slider para nuestra aplicación, solo quedaría añadir el contenido que se desee para finalizar y completar nuestro scroll con slider. Se podrían realizar modificaciones para añadir botones que permitan pasar de una página a otra del scroll, o modificar la situación del UILabel que nos indica a qué página iremos para adaptarlo a las distintas necesidades de la aplicación que deseemos desarrollar.