[Objective-c] Application iPhone, XML et UITableView
avril 26, 2009
Nous allons donc poursuivre le tutorial précédent qui permettait de parser un fichier XML, mais qui n’en faisait rien de spécial. Ici nous allons voir comment remplir un UITableView et afficher les informations d’un contact.
I) Introduction
Si vous avez suivi le tutorial sur comment parser un fichier XML, vous devez avoir une application de type Navigation-Based.
C’est à dire que votre application à 2 fichiers xib, MainWindow.xib et RootViewController.xib.
II) UITableView
Première chose, nous allons remplir notre UITableView. Dans RootViewController.h ajouter un NSMutableArray.
//RootViewController.h @interface RootViewController : UITableViewController { NSMutableArray *tableau; } |
Il faut maintenant remplir ce tableau. Nous allons modifier notre boucle dans RootViewController.m pour qu’elle ajoute un objet de type Contact dans chaque case du tableau.
//RootViewController.m - (void)viewDidLoad { tableau = [[NSMutableArray alloc] init]; NSURL *url = [NSURL URLWithString: @"http://www.jkraft.fr/testXml.xml"]; XMLToObjectParser *myParser = [[XMLToObjectParser alloc] parseXMLAtURL:url toObject:@"Contact" parseError:nil]; for(int i = 0; i < [[myParser items] count]; i++) { Contact *new = [[Contact alloc] init]; new = (Contact *)[[myParser items] objectAtIndex:i]; [tableau addObject:new]; [new release]; } [super viewDidLoad]; } |
Toujours dans RootViewController.m nous allons décommenter quelques fonctions qui concerne le UITableView et modifier certaines. Vous devez arriver à ce résultat.
//RootViewController.m - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } // Customize the number of rows in the table view. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [tableau count]; } // Customize the appearance of table view cells. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } NSString *ligneTableau = [NSString stringWithFormat:@"%@ %@", [[tableau objectAtIndex:indexPath.row] nom],[[tableau objectAtIndex:indexPath.row] prenom]]; cell.text=ligneTableau; // Configure the cell. return cell; } |
Ligne 8, on indique au TableView combien de ligne il aura, c’est à dire combien d’élément il y a dans mon tableau. Et ligne 20-21 je concatène le nom et le prénom et je l’écris dans la cellule du TableView. Compiler et éxécuter l’application et vous devriez avoir quelque chose qui ressemble à ça si vous utilisez mon fichier XML.
III) La fiche contact
Maintenant que nous avons la liste des contacts nous aimerions pouvoir en choisir un et afficher le reste des informations.
D’abord ajoutez une nouvelle classe de type UIViewController SubClass et nommez la ContactViewController. Vous avez donc 2 nouveaux fichiers, ContactViewController.h et ContactViewController.m
Nous voulons afficher nos 4 informations, on va donc créer 4 IBOutlets de type UILabel et un champs MonContact de type Contact qui contiendra notre objet courant. N’oubliez pas d’ajouter le Contact.h pour que le compilateur sache ce qu’est l’objet Contact.
//ContactViewController.h #import #import "Contact.h" @interface ContactViewController : UIViewController { IBOutlet UILabel *nom; IBOutlet UILabel *prenom; IBOutlet UILabel *tel; IBOutlet UILabel *email; Contact *MonContact; } @property (nonatomic, retain) UILabel *nom; @property (nonatomic, retain) UILabel *prenom; @property (nonatomic, retain) UILabel *tel; @property (nonatomic, retain) UILabel *email; @property (nonatomic, retain) Contact *MonContact; @end |
//ContactViewController.m #import "ContactViewController.h" @implementation ContactViewController @synthesize nom,prenom,tel, email , MonContact; - (void)viewDidLoad { prenom.text=MonContact.prenom; tel.text=MonContact.tel; nom.text=MonContact.nom; email.text=MonContact.email; [super viewDidLoad]; } |
Et voilà, il ne reste plus qu’à définir la vue. Ajouter donc un nouveau fichier de type View Xib dans l’onglet User Interface avec le nom : ContactView.xib. Ajouter des labels, et reliez les au IBOutlets pour arriver à ceci.
Il reste une dernière chose à faire, car si vous compilez, lorsque vous cliquez sur un des éléments du TableView rien ne se passe. Il faut pour cela, modifier une dernière fois le fichier RootViewController.m et rajouter cette fonction.
// Override to support row selection in the table view. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Navigation logic may go here -- for example, create and push another view controller. ContactViewController *contactViewController = [[ContactViewController alloc] initWithNibName:@"ContactView" bundle:nil]; contactViewController.MonContact=[tableau objectAtIndex:indexPath.row]; self.navigationItem.title=[[tableau objectAtIndex:indexPath.row] nom]; [self.navigationController pushViewController:contactViewController animated:YES]; [contactViewController release]; } |
Ligne 5 on affecte l’objet Contact sélectionné dans contactViewController.
Ligne 6, on affiche dans la NavigationBar le nom du contact sélectionné.
Compilez et voilà. Nous affichons les détails pour chaqu’un des contacts de votre fichier XML!
Téléchargez les fichiers sources si vous avez un soucis.
Catégorie(s): Développement, Iphone, Objective-C, Tutorial | Comments (26)
On peut même supprimer un peu plus de code en utilisant les « bindings » dans Interface Builder, mais j’imagine que ce sera le sujet de la troisième partie de ce tutoriel?
A quand une version vidéo? Nous serions heureux de la publier sur CocoaCast.com.
Amicalement,
~Philippe
Et bien, je suppose qu’on peut l’améliorer. Ce n’est pas prévu pour le moment, mais je suis preneur de tous conseils !
Super tuto, très claire et tres simple à utiliser. Un grand merci à toi!!!
Super, tes tutos vont très certainement m’aider énormément! 😉
Merci jerome, au fait je n ai toujours pas eu le temps de le faire, mais je t’ai emailé, bonne journée !
Bonsoir,
J’ai un problème a la compilation du code.
Quand je compile j’ai 3 erreurs :
@synthesize window;
error : @synthesize property must be in implementation context
@synthesize navigationController;
error : @synthesize property must be in implementation context
– (void)applicationDidFinishLaunching:(UIApplication *)application {
fatal error : method definition not in @implementation context
Quelqu’un aurait-il une idée d’ou peut provenir mon erreur.
Cordialement,
pun1ch3ur
Bonjour j’ai un souci sur la derniere partie, pour afficher les infos du contacts j’ai une erreur lorsque je clique sur une cellule :
Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘-[UIViewController _loadViewFromNibNamed:bundle:] loaded the « ContactView » nib but the view outlet was not set.
Je suppose que l’erreur viens de mon fichier xib mais je ne voit pas. Ce serait possible d’avoir les sources ?
C’est surement parce que tu n’as pas lié un élément dans Interface Builder!
J’ai exactement le même soucis que Kiki. Et j’ai beau faire et refaire ce tuto je n’arrive pas à afficher la vue avec le détail des informations.
Merci Kraft pour l’info mais perso je ne vois du tout à quoi c’est dû.
Quelqu’un aurait une idée svp?
malheureusement non , philippe … L’OS de l’iPhone ne gère pas les bindings comme le fait Mac OS X … du moins pour l’instant 😉
Pourquoi ça n’affiche pas le détail du contact ?
Dans son code, on appelle le nouveau ViewController de cette manière :
ContactViewController *contactViewController = [[ContactViewController alloc] initWithNibName:@ »ContactView » bundle:nil];
Quand vous avez crée le nouveau ViewController, vous avez cliqué sur le bouton « Créer aussi un fichier XIB » que XCode a appelé ContactViewController or dans le tutoriel, on le crée à la main et on l’appelle ContactView.
Donc pour appeler le ViewController, il faut plutôt écrire :
ContactViewController *contactViewController = [[ContactViewController alloc] initWithNibName:@ »ContactViewController » bundle:nil];
🙂
Superbe TûT !!!!
C’est le premier qui m’a permit de comprendre l’intégralité du Process d’implémentation.
Cependant ca ne marche pas chez moi car ca ne veut pas remplir le tableau « tableau » en mode debug je vois bien l’objet « new » se remplir mais n’intègre pas l’objet « tableau »
De plus je ne passe pas n’ont plus dans la partie concaténation du nom et prénom.
Quelqu’un a une idée que je puisse enfin finaliser un projet 🙂
Encore merci et bonne continuation
Pour Kiki et Seb,
j’ai eu le même problème sur le click d’une cellule.
en fait, à la création de ton objet « ContactViewController », il est hérité de « UITableViewController » et en fait il faut qu’il hérite de « UIViewController ».
Tout simplement.
Bonne continuation
Bonjour,
Merci pour le tuto !
J’ai tout de même une question :
Comment atteindre un attribut d’un noeud ?
exemple :
Merci d’avance 🙂
Sawyeur.
Bjr, merci pour ce tuto
Ttf j’ai un pb.
J’ai bien fait les 2 fichiers ContactViewController et le ContactView.xib.
Mais dans IB, je n’arrive pas a voir mes IBOutlet…
J’ai manqué quoi ?
… 1000 excuses pour le bruit, je viens de trouver!
Réponse pour ceux qui ont cherché comme moi:
Dans IB, il faut indiquer que la classe ContactViewController va controler ContactView.xib
Cela se fait dans l’Identity inspecteur.
Et iPhonez bien
Enfin un tuto pédagogique qui me fait bien avancer!
Mais, je voudrais savoir s’il est possible de faire une saisie dans ContactView pour faire la maj d’un contact?
Merci
Merci pour ce tutoriel fort utile qui va être la base d’une application client/serveur dialoguant avec une API.
Bonne continuation,
Pierre
Bonjour,
dans un premier temps merci pour ce tutoriel bien expliqué. Auriez vous une piste pour pouvoir afficher que les données relatives à ce que l’utilisateur voudrait. Ex : l’utilisateur entre le nom d’un contact et il récupère les informations relatives à ce contact et pas toute la table. En gros pourriez-vous me fournir une piste pour effectuer ce genre de requêtes?
Merci d’avance et bonne continuation.
très bon tuto! j’ai tout réussi du premier coup!
merci beaucoup en plus c’est super bien expliqué j’ai compris pas mal de notions 🙂
Malheureusement le tuto ne fonctionne plus. Il y a eu quelques modifications du sdk depuis sa parution, du coup certains méthodes ne renvoient plus rien.
Serait il possible de le mettre à jour 😀 ?
En tout cas merci quand meme 🙂
Oui effectivement, il faut ecrire cell.textLabel.text
au lieu de simplement cell.text
Good tuto !
Ca m’intrigue !
J’me demande comment font des applis de recherche d’annonces comme la centrale, si c’est pas tout simplement un xml qui est intéroggé à distance :o) vu qu’il me semble que c’est possible via un code comme le tient.
En tout cas merci
Y a des chances oui.
Bonjour
Merci pour ce tuto qui fonctionne très bien, ma question serait de savoir si il était possible d’interroger plusieurs XML, je m’explique par exemple
1.xml
1
Administratif – secrétariat
2
Informatique
2.xml
Avantage de l’admninistratif
1
en gros le id_ serait celui du 1.xml
Cela est possible ?
Oui bien sur.