Este tutorial es una continuación de la Guerra de las palabras El proyecto de lector de iPad mostrará cómo navegar un PDF con un UISlider cuando se usa el proyecto Leaves. En el camino, haremos algunos cambios estéticos para hacer que la interfaz sea un poco más inmersiva..
En el tutorial de la semana pasada, le presenté el proyecto de código abierto Leaves y demostré cómo configurar un lector de PDF básico. Sin embargo, la implementación básica de Leaves dejó mucho que desear desde el punto de vista de la experiencia del usuario. Específicamente, sugerí las siguientes mejoras:
El 60% de los participantes de la encuesta votaron para ver tutoriales adicionales sobre la adición de una Tabla de contenido o un UISlider, así que eso es lo que estaremos logrando hoy. Otra encuesta se ha incluido en esta publicación, por lo que si desea ver funciones adicionales agregadas a este proyecto o si prefiero pasar a otro tema del SDK de iOS, avíseme.!
Este es un video de demostración de lo que creará este tutorial:
Al final de este tutorial, debe tener una buena comprensión de cómo el UISlider
Objetos y una mejor comprensión de los aspectos internos del proyecto Leaves..
Comenzaremos por preparar la interfaz para tener un UISlider
. Experimenté con algunos enfoques diferentes aquí, pero al final decidí instalarme en un diseño que no había visto en ningún otro lugar: reduje la visualización del libro, lo centré en el centro de la pantalla y luego agregué un fondo de algunos Galaxia distante para un efecto temático. Entonces simplemente centré la UISlider
debajo del libro. Realmente me gusta la forma en que resultó esto, pero admito que este no es el enfoque más práctico. Al crear una aplicación de lector, tiene sentido que el texto cubra la pantalla completa como lo hizo en nuestra última construcción del proyecto, pero el lado positivo de agregar algo de relleno alrededor del libro es que potencialmente puede crear una interfaz de usuario más inmersiva. Eso es lo que he tratado de lograr aquí..
Para hacer lo mismo, abre el WOTWViewController.xib expediente. Arrastrar un UIImage
en la vista del iPad, y ajuste el tamaño de la imagen para que ocupe toda la pantalla (asegúrese de que la vista esté configurada en modo Retrato). A continuación, seleccione el inspector de atributos para el UIImage
y establecer el imagen campo "space.png" (puede encontrar este archivo en la carpeta "Recursos" de la descarga de esta publicación). Ahora tenemos una imagen de fondo mucho más fresca para el proyecto. Esto podría ser fácilmente personalizado para un género que no sea Ciencia Ficción..
A continuación, arrastre un UISlider
Objeto en la vista. Con el UISlider
seleccionado, vaya al "inspector de tamaño". Establezca el ancho del objeto en 360, la posición X en 204 y la posición Y en 955. El UISlider ahora debe colocarse cerca de la parte inferior de la pantalla, y justo debajo de donde se mostrará el libro..
En este punto necesitamos sincronizar el UISlider
en Interface Builder con una propiedad en nuestro controlador de vista WOTW. Con el archivo XIB aún abierto, haga clic en la pestaña Editor asistente en la barra de herramientas de Xcode. Al hacerlo, se abrirá una ventana de editor que debería contener el WOTWViewController.h archivo (si contiene un archivo diferente, seleccione el correcto del icono "Archivos relacionados" en la parte superior izquierda del panel del editor). Ahora, CTRL + Clic en la UISlider
en el archivo XIB y arrastre la línea que aparece sobre el panel de la ventana del editor. Suelte cuando la ventana emergente dice "Insertar Outlet, Acción o Colección de Outlet". Aparecerá un diálogo solicitándole un nombre para la conexión de IBOutlet. Nombra la salida pageSlider
y haga clic en conectar. Interface Builder ahora agregará el código necesario para que esta salida se use en su proyecto.
Como se mencionó en el primer tutorial de esta serie, el LeavesViewController
la clase contiene un Vista
llamado hojasVer
donde realmente se produce el dibujo de la página. El marco de hojasVer
está configurado para reflejar el LeavesViewController
en el loadView
método, como se muestra a continuación:
LeavesViewController.m
- (void) loadView [super loadView]; leavesView.frame = self.view.bounds; leavesView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.view addSubview: leavesView];
En nuestro caso, queremos el hojasVer
Marco para llenar solo un subconjunto del controlador de vista, no toda la pantalla.
Tenemos un par de opciones aquí. La solución más fácil parece ser simplemente cambiando el tamaño de la hojasVer
marco manualmente en la línea 3 anterior en el LeavesViewController.m expediente. Sin embargo, recordarás que LeavesViewController
es parte del código oficial del proyecto Leaves y todos nuestros cambios hasta ahora se han realizado en WOTWViewController
, que es una subclase de LeavesViewController
. En general, este es un enfoque mucho más fácil de mantener que la alternativa: piratear el código del proyecto para satisfacer las necesidades específicas de su situación y luego luchar continuamente con las actualizaciones del proyecto mediante la combinación repetitiva o la reescritura de los cambios comunitarios. En tal escenario, se encontrará a usted mismo voluntariamente descuidando las últimas versiones estables del proyecto. No quieres quedarte atrapado en esta situación..
Entonces, ¿cuál es una mejor alternativa? Porque hemos heredado el hojasVer
objeto en WOTWViewController
, Solo podemos hacer nuestros cambios en el -(void) viewDidLoad
método.
En WOTWViewController.m, Agregue las siguientes líneas de código:
- (void) viewDidLoad [super viewDidLoad]; [self-> leavesView setFrame: CGRectMake (0.0f, 0.0f, 563.0f, 845.0f)]; [self-> leavesView setCenter: self.view.center];
En la línea 3 anterior llamamos al LeavesViewController
implementación de loadView
, y luego personalizamos el hojasVer
marco por nuestra cuenta. La línea 4 establece el marco a un ancho y alto que me parece adecuado, y la línea 5 centra el marco en el centro de nuestro controlador de vista WOTW.
NOTA: ¿Se pregunta por qué estoy usando la sintaxis funky para acceder a la hojasVer
¿objeto? Ahí parece ser un error en GCC 4.2.1 que requiere esto. Comentarios con mayor conocimiento muy apreciado.
Si crea y ejecuta el proyecto ahora, debería ver el lector de WOTW en el centro de la pantalla con un control deslizante debajo para la navegación. Por supuesto, el control deslizante aún no funciona, así que sigamos rodando!
Cuando se inicie nuestra aplicación, queremos establecer los valores mínimo, máximo y actual del control deslizante en función del PDF cargado para la aplicación. También debemos especificar qué debe ocurrir cuando cambia el valor del control deslizante. Haremos esto en el WOTWViewController.m Archivo con las siguientes líneas de código:
- (void) viewDidLoad [super viewDidLoad]; [self-> leavesView setFrame: CGRectMake (0.0f, 0.0f, 563.0f, 845.0f)]; [self-> leavesView setCenter: CGPointMake (self.view.center.x, self.view.center.y - 20.0f)]; [self.pageSlider addTarget: self action: @selector (turnPageWithSlider :) para ControlEvents: UIControlEventValueChanged]; self.pageSlider.minimumValue = 0.0; self.pageSlider.maximumValue = (float) ([self numberOfPagesInLeavesView: self-> leavesView] - 1); self.pageSlider.value = self-> leavesView.currentPageIndex;
La línea 8 anterior establece un selector que debe llamarse cuando cambia el valor del control deslizante. Por defecto, se llamará al selector. continuamente como el botón deslizante se mueve. Sin embargo, puede desactivar esto configurando el control deslizante continuo
valor a "NO", lo que hará que solo se llame al selector después de que se suelte el botón deslizante.
La línea 9 anterior establece el valor mínimo en 0. Esto es apropiado porque se hace referencia al PDF en Hojas con un índice basado en 0.
La línea 10 anterior llama al numberOfPagesInLeavesView:
método para establecer el valor máximo del control deslizante y se ajusta para un índice basado en 0 restando 1 del resultado.
Finalmente, la línea 11 establece el valor actual del control deslizante en hojasVer
propiedad currentPageIndex
.
Ahora escribiremos la lógica que debería ocurrir cuando el turnPageWithSlider:
selector se llama.
Agregue el siguiente código en el archivo de implementación de WOTW:
- (void) turnPageWithSlider: (id) sender int pageIndex = (int) [valor de self.pageSlider]; [self.pageSlider setValue: (float) pageIndex]; self-> leavesView.currentPageIndex = pageIndex;
El valor devuelto de un UISlider
es de la flotador
tipo de datos. En la línea 3 de arriba, encasillamos este valor a un entero y lo almacenamos en el índice de página
variable.
En la línea 4, hacemos lo contrario: encasillamos índice de página
a un flotador y luego actualizar el valor del control deslizante. ¿Cuál es el punto de? ¿No es esto redundante? No, porque cuando encajamos el valor del control deslizante en un entero, eliminamos el resto. Esto es importante porque no queremos pasar, por ejemplo, a la página 1.23 o 20.56, queremos pasar a la página 1 o 20. Este paso obliga al usuario a recorrer el PDF de la manera que se espera..
La línea 5 de arriba establece el hojasVer
propiedad página actual
, que también forzará automáticamente una actualización de la pantalla del libro.
Si crea y ejecuta el proyecto ahora, debería poder desplazarse por el libro. Sin embargo, falta un detalle importante: si gira las páginas arrastrándolas manualmente, el valor del control deslizante seguirá siendo el mismo. Para esto tendremos que aprovechar el delegado de LeavesView.
La vista de hojas personalizada proporciona varios métodos de delegado que se llaman en puntos clave de la animación. Uno de esos es leavesView: didTurnToPageAtIndex:
. Agregue la siguiente lógica para actualizar el control deslizante cuando se llame a este método delegado:
- (void) leavesView: (LeavesView *) leavesView didTurnToPageAtIndex: (NSUInteger) pageIndex if ((int) self.pageSlider.value! = pageIndex) self.pageSlider.value = (float) pageIndex;
Con el código anterior en su lugar, nuestra implementación del control deslizante debe estar completa!
Como mencioné al comienzo de este tutorial, todavía hay muchas características que podrían agregarse a este proyecto. Si desea que continúe esta serie, vote por la función que le gustaría ver a continuación. De lo contrario, puede votar por mí para pasar a un tema del SDK de iOS completamente diferente (no dude en sugerir uno en la sección de comentarios). La encuesta cerrará el sábado por la mañana, 10 de septiembre..