Travailler avec UIRefreshControl

Lorsque Loren Brichter a introduit l'idée de «tirer pour actualiser» dans Tweetie 2 il y a quelques années, les développeurs ont rapidement commencé à adopter ce concept ingénieux et intuitif. Bien que Twitter détienne maintenant le brevet sur le concept "tirer pour actualiser", cela n’a pas empêché Apple de présenter le UIRefreshControl classe dans iOS 6. Cette nouvelle UIControl la sous-classe rend trivial l'ajout d'un contrôle "tirer pour actualiser" à tout contrôleur de vue de table sous iOS 6.


Court et doux

La référence de classe de UIRefreshControl est court et laisse deviner à quel point il est facile de commencer avec cet ajout du framework UIKit. le UIRefreshControl la classe descend directement de UIControl, ce qui signifie que la mise en place d'une instance de UIRefreshControl n’est pas très différent de la création et de la configuration d’un autre contrôle UIKit. Après avoir instancié une instance de UIRefreshControl classe, vous l'assignez à la nouvelle refreshControl propriété d'un objet contrôleur de vue de table (UITableViewController ou une sous-classe de celui-ci). Le contrôleur de vue de table se charge de positionner et d'afficher correctement le contrôle d'actualisation. Comme avec tout autre UIControl sous-classe, vous attachez une paire cible-action à un événement spécifique, UIControlEventValueChanged dans le cas de UIRefreshControl.

Ce ne serait pas un tutoriel Mobiletuts + sans un exemple illustrant comment utiliser le UIRefreshControl classe dans un projet. Dans la suite de ce didacticiel, je vais vous montrer comment remplir une vue sous forme de tableau avec une liste de tweets tirés de l'API de recherche Twitter. La demande est envoyée à l'API de recherche de Twitter lorsque l'utilisateur extrait la vue de la table à l'aide de la commande Pull-to-refresh..


Étape 1: Configuration du projet

L’application que nous sommes sur le point de créer interroge l’API de recherche Twitter pour des tweets sur développement iOS. La demande est envoyée à l'API de recherche de Twitter lorsque l'utilisateur retire la vue du tableau, révélant ainsi le contrôle d'actualisation. Nous allons utiliser la fantastique bibliothèque AFNetworking pour envoyer notre demande à l'API de recherche Twitter. AFNetworking nous aidera également à télécharger et à afficher des images de profil de manière asynchrone.

Créez un nouveau projet dans Xcode en sélectionnant le Application vide template de la liste des templates (Figure 1). Nommez votre application Tirer pour rafraîchir, entrez un identifiant d'entreprise, définissez iPhone pour la famille d'appareils, et vérifiez Utiliser le comptage automatique des références. Le reste des cases à cocher peut ne pas être coché pour ce projet (figure 2). Indiquez à Xcode où vous souhaitez enregistrer le projet et appuyez sur le bouton Créer bouton.


Étape 2: Ajout de la bibliothèque AFNetworking

Installer AFNetworking à l'aide de Cocoapods est un jeu d'enfant. Cependant, dans ce didacticiel, je vais vous montrer comment ajouter manuellement la bibliothèque AFNetworking à un projet Xcode pour vous assurer que nous sommes tous sur la même page. Ce n'est pas si difficile.

Téléchargez la dernière version stable de la bibliothèque à partir de sa page de projet GitHub, extrayez l'archive et faites glisser le dossier nommé AFNetworking à votre projet Xcode. Assurez-vous que la case à cocher intitulée Copier des éléments dans le dossier du groupe de destination (si nécessaire) est vérifié et vérifiez que la bibliothèque est ajoutée à la Tirer pour rafraîchir cible (figure 3).

La bibliothèque AFNetworking repose sur deux frameworks auxquels un nouveau projet Xcode n'est pas lié par défaut, à savoir (1) les frameworks de configuration du système et (2) de Mobile Core Services. Sélectionnez votre projet dans le Navigateur de projet, choisir la Tirer pour rafraîchir cible dans la liste des cibles et ouvrez le Phases de construction onglet en haut. Étendre le Lien binaire avec des bibliothèques tiroir et ajoutez les deux cadres en cliquant sur le bouton plus (figure 4).

Pour finir, ajoutez une instruction d'importation pour les deux cadres ainsi que AFNetworking au fichier d'en-tête précompilé des projets, comme indiqué dans l'extrait de code ci-dessous. Cela facilitera le travail avec AFNetworking car nous n'avons pas besoin d'ajouter d'instruction d'importation à chaque classe pour laquelle nous souhaitons utiliser la bibliothèque..

 // // En-tête de préfixe pour tous les fichiers source de la cible "Extraire pour actualiser" dans le projet "Extraire pour actualiser" // #import  #ifndef __IPHONE_3_0 #warning "Ce projet utilise des fonctionnalités uniquement disponibles dans iOS SDK 3.0 et versions ultérieures." #endif #ifdef __OBJC__ #import  #importation  #importation  #importation  #import "AFNetworking.h" #endif

Étape 3: Création du contrôleur de vue de table

le UIRefreshControl est conçu pour fonctionner en conjonction avec un objet contrôleur de vue table. Créer un nouveau UITableViewController sous-classe (Fichier> Nouveau> Fichier… ) en choisissant le Classe Objective-C template de la liste des templates (figure 5). Nommez la nouvelle classe MTTweetsViewController et vérifiez que c'est un UITableViewController sous-classe. Indiquez à Xcode qu'il ne devrait pas créer de fichier nib pour la nouvelle classe de contrôleur en décochant la case à cocher intitulée Avec XIB pour l'interface utilisateur (figure 6). Spécifiez un emplacement pour enregistrer la nouvelle classe et cliquez sur le bouton Créer bouton.


Étape 4: Ajout du contrôle de rafraîchissement

Avant de pouvoir ajouter le contrôle de rafraîchissement au contrôleur de vue de table, nous devons instancier une instance du nouveau MTTweetsViewController classe. Mettre à jour le application: didFinishLaunchingWithOptions: méthode en MTAppDelegate.m comme indiqué ci-dessous. L'implémentation ne devrait pas contenir de surprises. Nous initialisons une instance du MTTweetsViewController classe et définissez-le comme contrôleur de vue racine de la fenêtre de l'application. N'oubliez pas d'ajouter une déclaration d'importation en haut de MTAppDelegate.m importer le fichier d'en-tête du MTTweetsViewController classe.

 - (BOOL) application: (UIApplication *) application didFinishLaunchingWithOptions: (NSDictionary *) launchOptions // Initialise le contrôleur d'affichage View Tweet MTTweetsViewController * vc = [[MTTweetsViewController alloc] initWithStyle: UITableViewStylePlain]; // Initialize Window self.window = [[UIWindow alloc]] initWithFrame: [[UIScreen mainScreen]]]]; // Configurer la fenêtre [self.window setBackgroundColor: [UIColor whiteColor]]; [self.window setRootViewController: vc]; // rendre la clé et visible [self.window makeKeyAndVisible]; retourner OUI; 
 #import "MTTweetsViewController.h"

Si vous exécutez l'application dans le simulateur iPhone, vous devriez voir une vue sous forme de tableau vide. Le contrôle d'actualisation est ajouté dans le viewDidLoad méthode du contrôleur de vue tweets. Comme je l'ai mentionné précédemment, l'ajout d'un contrôle d'actualisation est très simple. Jetez un coup d’œil à la mise en œuvre de la viewDidLoad méthode indiquée ci-dessous. Nous initialisons le contrôle de rafraîchissement et ajoutons une cible et une action pour le UIControlEventValueChanged événement du contrôle d'actualisation. Enfin, le contrôle de rafraîchissement est attribué à la refreshControl propriété du contrôleur de vue de table. Bien sûr, le refreshControl la propriété est également nouvelle pour iOS 6.

 - (void) viewDidLoad [super viewDidLoad]; // Initialise le contrôle de rafraîchissement UIRefreshControl * refreshControl = [[UIRefreshControl alloc] init]; // Configurer le contrôle d'actualisation [refreshControl addTarget: action automatique: @selector (refresh :) forControlEvents: UIControlEventValueChanged]; // Configurer View Controller [self setRefreshControl: refreshControl]; 

Avant de construire et d’exécuter à nouveau le projet, nous devons mettre en œuvre le rafraîchir: action dans le fichier d'implémentation du contrôleur de vue. Pour vérifier que tout est correctement configuré, nous enregistrons simplement un message sur la console. Générez et exécutez le projet pour voir le contrôle d'actualisation en action.

 - (void) refresh: (id) expéditeur NSLog (@ "Rafraîchissant"); 

Vous remarquerez que le contrôle d'actualisation ne disparaît pas après son affichage par le contrôleur de vue de table. C'est quelque chose que vous devrez faire vous-même. L’idée derrière le contrôle de rafraîchissement est en quelque sorte similaire à la vue d’indicateur d’activité de UIKit (UIActivityIndicatorView), c’est-à-dire que vous êtes responsable de le montrer et de le cacher. Cacher le contrôle de rafraîchissement est aussi simple que de lui envoyer un message endRefreshing. Mettre à jour le rafraîchir: action comme indiqué ci-dessous et relancez l'application dans le simulateur iPhone.

 - (void) refresh: (id) expéditeur NSLog (@ "Rafraîchissant"); // End Refreshing [(UIRefreshControl *) sender endRefreshing]; 

Le contrôle d'actualisation disparaît immédiatement après que vous avez libéré la vue tabulaire. Bien sûr, cela rend le contrôle d'actualisation totalement inutile. Ce que nous allons faire, c'est envoyer une demande à l'API de recherche Twitter et masquer le contrôle d'actualisation lorsque nous recevons une réponse (ou lorsque la demande expire). AFNetworking rend cela très facile à faire.


Étape 5: Interrogation de l'API de recherche Twitter

Nous allons stocker les tweets que nous recevons de l'API de recherche Twitter dans un tableau. Ajouter une propriété privée nommée tweets au MTTweetsViewController classe comme ci-dessous.

 #import "MTTweetsViewController.h" @interface MTTweetsViewController () @property (fort, non atomique) NSArray * tweets; @fin

Ensuite, mettez à jour le numberOfSectionsInTableView:, tableView: numberOfRowsInSection:, et tableView: cellForRowAtIndexPath: méthodes comme indiqué ci-dessous. Si vous avez déjà utilisé des vues de table, cela ne devrait pas être trop difficile à comprendre..

 - (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.tweets? dix; 
 - (NSInteger) tableView: (UITableView *) numéro de la table (numéro de vue) de la section (): section (NSInteger) retour [nombre de self.tweets]? [compte.de.weets personnels]: 0; 
 - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath statique NSString * CellIdentifier = @ "Identificateur de cellule"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; if (! cell) cell = [[UITableViewCell alloc]] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: CellIdentifier];  // Récupérer le tweet NSDictionary * tweet = [self.tweets objectAtIndex: [rangéeIndexPath]]; // Configure Cell [cell.textLabel setText: [tweet objectForKey: @ "text"]]; [cell.detailTextLabel setText: [tweet objectForKey: @ "from_user"]]; // Télécharger une image de profil de façon asynchrone NSURL * url = [NSURL URLWithString: [tweet objectForKey: @ "profile_image_url"]]; [cell.imageView setImageWithURL: url placeholderImage: [UIImage imageNamed: @ "placeholder"]]; cellule de retour; 

Dans tableView: cellForRowAtIndexPath:, nous créons une nouvelle cellule (ou supprimons la file d'attente d'une cellule réutilisable) et la remplissons du contenu d'un tweet. Pour nous assurer que la vue de table défile sans à-coups, nous téléchargeons l'image de profil de l'utilisateur de manière asynchrone. Ceci est très facile à réaliser avec AFNetworking car cela nous donne setImageWithURL: placeholderImage:. Cela permet de définir la vue d'image de la cellule avec l'image de substitution fournie tout en demandant l'image de profil de l'utilisateur en arrière-plan. Pour que cela fonctionne, ajoutez placeholder.png et [email protected] à votre projet Xcode. Vous pouvez trouver les deux fichiers dans les fichiers source de ce tutoriel..

Nous envoyons notre demande à l'API de recherche Twitter dans le rafraîchir: action. Jetez un coup d'œil à la mise à jour ci-dessous. Je ne vais pas entrer dans les détails de la façon dont le AFJSONRequestOperation La classe fonctionne dans ce tutoriel, mais je veux expliquer comment fonctionne le flux de la demande. Après avoir spécifié l'URL de la requête (NSURL) et initialiser la requête d'URL (NSURLDemande), nous créons une opération de requête JSON en passant (1) la requête d’URL, (2) un bloc de succès et (3) un bloc d’échec à JSONRequestOperationWithRequest: succès: échec:. Le bloc de succès est exécuté si la requête a abouti et nous donne la réponse de la requête sous forme d'instance de NSDictionary. Nous extrayons le tableau de tweets que nous avons demandé, mettons à jour le tweets propriété, rechargez la vue tableau pour afficher les tweets et masquez le contrôle de rafraîchissement en lui envoyant un message endRefreshing.

 - (void) refresh: (id) expéditeur // Créer une URL NSURL * url = [NSURL URLWithString: @ "http://search.twitter.com/search.json?q=ios%20development&rpp=100&include_entities=true&result_type=mixed/ "]; // Initialize URL Request NSURLRequest * urlRequest = [[NSURLRequest alloc] initWithURL: url]; // Opération de demande JSON Opération AFJSONRequestOperation * = [AFJSONRequestOperation JSONRequestOperationWithRequest: succès urlRequest: ^ (requête NSURLRequest *, NSHTTPURLResponse *, id JSON) = résultats (NSArray *) = if ((nombre de résultats)) self.tweets = results; // Reload Table View [self.tableView reloadData]; // End Refreshing [(UIRefreshControl *) sender endRefreshing];  échec: ^ (demande NSURLRequest *, réponse NSHTTPURLResponse *, erreur NSError *, id JSON) // End Refreshing [(UIRefreshControl *) expéditeur endRefreshing]; ]; // Start Operation [opération start]; 

Si la demande échoue, nous ne masquons que le contrôle d'actualisation. Bien entendu, il serait préférable d'informer l'utilisateur que la demande a échoué, mais cela suffira pour notre exemple. Nous envoyons la demande en démarrant l'opération de demande JSON à la fin du processus. rafraîchir: action.

Générez et exécutez le projet une fois de plus pour voir l'application exemple en action. Si les images de profil ne s'affichent pas correctement, vérifiez à nouveau que vous avez ajouté les images d'espace réservé que j'ai mentionnées précédemment à votre projet..


Conclusion

De nombreuses bibliothèques tentent d'imiter la fonctionnalité d'origine "Tirer pour actualiser", mais il est agréable de voir qu'Apple a finalement adopté ce concept intéressant et l'a inclus dans le cadre UIKit. Comme vous avez pu le constater, dans iOS 6, Apple a déjà mis le UIRefreshControl classe à utiliser dans certaines de ses propres applications, telles que l'application Podcasts.