Trabajando con UIRefreshControl

Cuando Loren Brichter presentó la idea de "tirar para actualizar" en Tweetie 2 hace unos años, no pasó mucho tiempo antes de que los desarrolladores comenzaran a adoptar este concepto ingenioso e intuitivo. A pesar de que Twitter ahora posee la patente sobre el concepto de "tirar para actualizar", esto no ha impedido que Apple introduzca la UIRefreshControl clase en iOS 6. Este nuevo UIControl La subclase hace que sea trivial agregar un control de "extracción para actualizar" a cualquier controlador de vista de tabla en iOS 6.


Corto y dulce

La referencia de clase de UIRefreshControl es breve, aludiendo a lo fácil que es comenzar con esta adición del marco UIKit. los UIRefreshControl la clase desciende directamente de UIControl, lo que significa que la creación de una instancia de UIRefreshControl no es muy diferente de crear y configurar cualquier otro control UIKit. Después de instanciar una instancia de la UIRefreshControl clase, la asignas a la nueva refreshControl propiedad de un objeto controlador de vista de tabla (UITableViewController o una subclase de ella). El controlador de vista de tabla se encarga de colocar y mostrar correctamente el control de actualización. Como con cualquier otro UIControl subclase, se adjunta un par objetivo-acción a un evento específico, UIControlEventValueChanged En el caso de UIRefreshControl.

Esto no sería un tutorial de Mobiletuts + sin un ejemplo que muestre cómo usar el UIRefreshControl clase en un proyecto. En el resto de este tutorial, te mostraré cómo rellenar una vista de tabla con una lista de tweets extraídos de la API de búsqueda de Twitter. La solicitud se envía a la API de búsqueda de Twitter cuando el usuario extrae la vista de tabla dow: pull-to-refresh.


Paso 1: Configuración del proyecto

La aplicación que estamos a punto de construir consulta la API de búsqueda de Twitter para tweets sobre desarrollo de iOS. La solicitud se envía a la API de búsqueda de Twitter cuando el usuario retira la vista de tabla hacia abajo, revelando el control de actualización. Usaremos la fantástica biblioteca AFNetworking para enviar nuestra solicitud a la API de búsqueda de Twitter. AFNetworking también nos ayudará a descargar y mostrar imágenes de perfil de forma asíncrona..

Crea un nuevo proyecto en Xcode seleccionando el Aplicación vacía Plantilla de la lista de plantillas (Figura 1). Nombra tu aplicación Pull-to-Refresh, ingrese un identificador de compañía, establezca iPhone Para la familia de dispositivos, y compruebe Utilice el conteo automático de referencias. El resto de las casillas de verificación pueden dejarse sin marcar para este proyecto (figura 2). Dile a Xcode dónde quieres guardar el proyecto y pulsa el botón Crear botón.


Paso 2: Agregando la Biblioteca de AFNetworking

Instalar AFNetworking usando Cocoapods es muy fácil. Sin embargo, en este tutorial, le mostraré cómo agregar manualmente la biblioteca AFNetworking a un proyecto de Xcode para asegurarse de que todos estemos en la misma página. No es tan dificil de todos modos.

Descargue la última versión estable de la biblioteca desde su página de proyecto de GitHub, extraiga el archivo y arrastre la carpeta llamada Red de redes a su proyecto Xcode. Asegúrese de que la casilla marcada Copie los elementos en la carpeta del grupo de destino (si es necesario) se comprueba y vuelve a comprobar que la biblioteca se ha agregado a la Pull-to-Refresh objetivo (figura 3).

La biblioteca AFNetworking se basa en dos marcos en los que un nuevo proyecto de Xcode no está vinculado de manera predeterminada, (1) los marcos de configuración del sistema y (2) los servicios básicos móviles. Seleccione su proyecto en el Navegador de proyectos, elegir la Tirar para actualizar objetivo de la lista de objetivos, y abra el Construir fases pestaña en la parte superior. Ampliar la Enlace Binario Con Bibliotecas Haga clic en el cajón y agregue ambos marcos haciendo clic en el botón más (figura 4).

Para terminar, agregue una declaración de importación para ambos marcos y AFNetworking al archivo de encabezado precompilado de los proyectos como se muestra en el fragmento de código a continuación. Esto hará que sea más fácil trabajar con AFNetworking, ya que no necesitamos agregar una declaración de importación a todas las clases en las que queremos usar la biblioteca..

 // // Encabezado de prefijo para todos los archivos de origen del destino 'Extracción para actualizar' en el proyecto 'Extracción para actualizar' // #import  #ifndef __IPHONE_3_0 #warning "Este proyecto utiliza funciones solo disponibles en iOS SDK 3.0 y versiones posteriores." #endif #ifdef __OBJC__ #import  #importar  #importar  #importar  #import "AFNetworking.h" #endif

Paso 3: Crear el controlador de vista de tabla

los UIRefreshControl está diseñado para trabajar en conjunto con un objeto controlador de vista de tabla. Crear un nuevo UITableViewController subclaseArchivo> Nuevo> Archivo ... ) eligiendo el Clase objetiva-c Plantilla de la lista de plantillas (Figura 5). Dale a la nueva clase un nombre de MTTweetsViewController y vuelva a comprobar que es una UITableViewController subclase Indique a Xcode que no debe crear un archivo de punta para la nueva clase de controlador desactivando la casilla de verificación etiquetada Con XIB para la interfaz de usuario. (figura 6). Especifique una ubicación para guardar la nueva clase y haga clic en Crear botón.


Paso 4: Agregar el control de actualización

Antes de poder agregar el control de actualización al controlador de vista de tabla, debemos crear una instancia de la nueva instancia. MTTweetsViewController clase. Actualizar el aplicación: didFinishLaunchingWithOptions: método en MTAppDelegate.m Como se muestra abajo. La implementación no debería contener sorpresas. Inicializamos una instancia del MTTweetsViewController Clase y configúrelo como el controlador de vista raíz de la ventana de la aplicación. No olvide agregar una declaración de importación en la parte superior de MTAppDelegate.m para importar el archivo de cabecera de la MTTweetsViewController clase.

 - Aplicación (BOOL): (UIApplication *) didFinishLaunchingWithOptions: (NSDictionary *) launchOptions // Initialize Tweet View Controller MTTweetsViewController * vc = [[MTTweetsViewController alloc] initWithStyle: UITableViewStylePlain]; // Inicializar la ventana self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] lines]]; // Configurar ventana [self.window setBackgroundColor: [UIColor whiteColor]]; [self.window setRootViewController: vc]; // Hacer clave y visible [self.window makeKeyAndVisible]; devuelve SÍ; 
 #importar "MTTweetsViewController.h"

Si ejecuta la aplicación en el Simulador de iPhone, debería ver una vista de tabla vacía. El control de actualización se añade en la viewDidLoad Método del controlador de vista de tweets. Como mencioné anteriormente, agregar un control de actualización es muy fácil. Eche un vistazo a la implementación del viewDidLoad método que se muestra a continuación. Inicializamos el control de actualización y agregamos un objetivo y una acción para el UIControlEventValueChanged evento del control de actualización. Finalmente, el control de actualización se asigna a la refreshControl Propiedad del controlador de vista de tabla. Por supuesto, el refreshControl La propiedad también es nueva para iOS 6.

 - (void) viewDidLoad [super viewDidLoad]; // Inicializar el control de actualización UIRefreshControl * refreshControl = [[UIRefreshControl alloc] init]; // Configurar el control de actualización [refreshControl addTarget: self action: @selector (refresh :) forControlEvents: UIControlEventValueChanged]; // Configurar View Controller [self setRefreshControl: refreshControl]; 

Antes de que construyamos y ejecutemos el proyecto una vez más, necesitamos implementar el refrescar: Acción en el archivo de implementación del controlador de vista. Para verificar que todo está configurado correctamente, simplemente registramos un mensaje en la consola. Genere y ejecute el proyecto para ver el control de actualización en acción.

 - (void) refresh: (id) sender NSLog (@ "Refreshing"); 

Notará que el control de actualización no desaparece después de que haya sido mostrado por el controlador de vista de tabla. Esto es algo que tendrás que hacer tú mismo. La idea detrás del control de actualización es en cierto modo similar a la vista del indicador de actividad de UIKit (UIActivityIndicatorView), es decir, usted es responsable de mostrarlo y ocultarlo. Ocultar el control de actualización es tan simple como enviarle un mensaje de EndRefreshing. Actualizar el refrescar: Acción como se muestra a continuación y ejecute la aplicación una vez más en el iPhone Simulator.

 - (void) refresh: (id) sender NSLog (@ "Refreshing"); // End Refreshing [(UIRefreshControl *) sender endRefreshing]; 

El control de actualización desaparece inmediatamente después de liberar la vista de tabla. Por supuesto, esto hace que el control de actualización sea bastante inútil. Lo que haremos es enviar una solicitud a la API de búsqueda de Twitter y ocultar el control de actualización cuando recibamos una respuesta (o cuando se agote el tiempo de la solicitud). AFNetworking hace que esto sea muy fácil de hacer..


Paso 5: Consultar la API de búsqueda de Twitter

Almacenaremos los tweets que recibimos de la API de búsqueda de Twitter en una matriz. Añadir una propiedad privada llamada tweets al MTTweetsViewController clase como se muestra a continuación.

 #importar "MTTweetsViewController.h" @interface MTTweetsViewController () @property (strong, nonatomic) NSArray * tweets; @fin

A continuación, actualice el numberOfSectionsInTableView:, tableView: numberOfRowsInSection:, y tableView: cellForRowAtIndexPath: métodos como se muestra a continuación. Si ha trabajado con vistas de tabla anteriormente, esto no debería ser demasiado difícil de entender.

 - (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.tweets? 1: 0; 
 - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sección return [self.tweets count]? [cuenta de self.tweets]: 0; 
 - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath static NSString * CellIdentifier = @ "Cell Identifier"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; if (! cell) cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: CellIdentifier];  // Fetch Tweet NSDictionary * tweet = [self.tweets objectAtIndex: [indexPath row]]; // Configurar celda [cell.textLabel setText: [tweet objectForKey: @ "text"]]; [cell.detailTextLabel setText: [tweet objectForKey: @ "from_user"]]; // Descargar la imagen del perfil de forma asíncrona NSURL * url = [NSURL URLWithString: [tweet objectForKey: @ "profile_image_url"]]; [cell.imageView setImageWithURL: url placeholderImage: [UIImage imageNamed: @ "placeholder"]]; celda de retorno 

En tableView: cellForRowAtIndexPath:, creamos una nueva celda (o sacamos de la cola una celda reutilizable) y la rellenamos con el contenido de un tweet. Para asegurarnos de que la vista de la tabla se desplace sin problemas, descargamos la imagen del perfil del usuario de forma asíncrona. Esto es muy fácil de lograr con AFNetworking, ya que nos da setImageWithURL: placeholderImage:. Lo que esto hace es configurar la vista de la imagen de la celda con la imagen de marcador de posición provista mientras se solicita la imagen de perfil del usuario en el fondo. Para hacer este trabajo, agregue placeholder.png y [email protected] a su proyecto Xcode. Puedes encontrar ambos archivos en los archivos fuente de este tutorial..

Enviamos nuestra solicitud a la API de búsqueda de Twitter en el refrescar: acción. Eche un vistazo a la implementación actualizada a continuación. No voy a entrar en los detalles de cómo AFJSONRequestOperation La clase funciona en este tutorial, pero quiero explicar cómo funciona el flujo de la solicitud. Después de especificar la URL de solicitud (NSURL) e inicializando la solicitud de URL (NSURLRequest), creamos una operación de solicitud JSON al pasar (1) la solicitud de URL, (2) un bloque de éxito y (3) un bloque de falla a JSONRequestOperationWithRequest: success: failure:. El bloque de éxito se ejecuta si la solicitud fue exitosa y nos da la respuesta de la solicitud como una instancia de NSDiccionario. Extraemos la matriz de tweets que solicitamos, actualizamos el tweets propiedad, vuelva a cargar la vista de tabla para mostrar los tweets y oculte el control de actualización enviándole un mensaje de EndRefreshing.

 - (void) refresh: (id) sender // Create URL NSURL * url = [NSURL URLWithString: @ "http://search.twitter.com/search.json?q=ios%20development&rpp=100&include_entities=true&result_type=mixed/ "]; // Inicializar solicitud de URL NSURLRequest * urlRequest = [[NSURLRequest alloc] initWithURL: url]; // Solicitud JSON Operación AFJSONRequestOperation * operation = [AFJSONRequestOperation JSONRequestOperationWithRequest: urlRequest success: ^ (NSURLRequest * request, NSHTTPURLResponder) SON if ([cuenta de resultados]) self.tweets = resultados; // Reload Table View [self.tableView reloadData]; // End Refreshing [(UIRefreshControl *) sender endRefreshing];  fallo: ^ (solicitud NSURLRequest *, respuesta NSHTTPURLResponse *, error NSError *, id JSON) // End Refreshing [(UIRefreshControl *) sender endRefreshing]; ]; // Iniciar operación [inicio de operación]; 

Si la solicitud falla, solo ocultamos el control de actualización. Por supuesto, sería mejor informar al usuario de que la solicitud falló, pero esto servirá para nuestro ejemplo. Enviamos la solicitud iniciando la operación de solicitud JSON al final de la refrescar: acción.

Genere y ejecute el proyecto una vez más para ver la aplicación de ejemplo en acción. Si las imágenes de perfil no se muestran correctamente, compruebe que haya agregado las imágenes de marcador de posición que mencioné anteriormente en su proyecto..


Conclusión

Hay muchas bibliotecas que intentan imitar la funcionalidad original de "tirar para actualizar", pero es bueno ver que Apple finalmente ha adoptado este concepto limpio y lo ha incluido en el marco UIKit. Como habrás notado, en iOS 6, Apple ya ha puesto el UIRefreshControl clase para usar en algunas de sus propias aplicaciones, como la aplicación Podcasts.