- General tags: - cocoa touch - code - développement - interface builder - iphone - objective-c - xcode Développer pour l'iPhone - Chapitre 1 - Partie 2 - Interface Builder | Cactus

Développer pour l'iPhone - Chapitre 1 - Partie 2 - Interface Builder

Interface Builder, une invention française cocorico =================================================== Si vous ne me croyez pas : Jean Marie Hullot Passé cette boutade, parlons un peu d'Interface Builder. Pour ceux qui ne connaissent pas, Interface Builder est une révolution pour le design d'interface. en tout cas il utilise un paradigme différent des autres interfaces de création d'interface. En effet Interface Builder ne crée pas un modèle de code qu'il faudra rééditer ensite, mais un document d'interface qu'il archive sous forme de fichier, pour le désarchiver à l'exécution. Ces fichiers .xib que vous voyez sont ( à peu de choses près) les mêmes que ceux qui sont dans votre application. Les objets y sont séchés à froid. Au désarchivage, on les reconnecte avec le code qui les concerne et ils reprennent vie. Dans les faits, ça donne ça : double cliquez sur SalutViewController.xib. Interface Builder s'ouvre et vous présente le contenu du bundle (paquet) du bundle j'ai dit, avec la vue principale ouverte et une bibliothèque d'objets disponibles. Pour utiliser les objets, on les met dans la vue, on les connecte avec le code, on sauvegarde et voilà. C'est tout. Pas de génération de code, rien. Et si on le faisait? Tout d'abord, dans Interface Builder, je préfère avoir la visualisation des objets en liste. Cette présentation en liste permet en effet de montrer l'arbre de tous les objets et la façon dont ils s'insèrent les uns dans les autres. Commençons par l'objet le plus rempli, MainWindow.xib : dans XCode, double cliquez dessus pour l'ouvrir. Vous avez une fenêtre avec cinq objets. Si vous choisissez l'affichage en liste, cela donne aussi cela. Le premier objet est SalutAppDelegate, un objet créé automatiquement pour vous à la création du projet. Il hérite de NSObject. Le second objet est window, qui représente la seule fenêtre de cette application. Sélectionnez votre SalutAppDelegate et faites apparaître la fenêtre de propriétés ⇧⌘1 ou Tools / Attributes inspector. Dans cette fenêtre il y a 4 onglets : attributs, connexion, tailles et identité. Le premier onglet ici ne sert à rien car SalutAppDelegate n'a aucun attribut qui se rapporte à l'interface. Le second onglet montre les différentes connexions qui peuvent être faites entre cet objet et les autres objets accessibles par interface builder. Ainsi, ici l'objet SalutAppDelegate a deux variables qui peuvent être liées à d'autres objets : viewController et window . La première est liée à l'objet SalutViewController présent juste en dessous, la deuxième est liée à la fenêtre Window. Pour le bénéfice de l'exercice, nous allons casser les liens faits automatiquement, et les refaire. Dans la fenêtre des connexions, cliquez sur la petite croix présente entre viewController et Salut View Controller, puis sur la petite croix présente entre window (la variable window de l'objet SalutAppDelegate) et Window (la fenête créée dans Interface Builder). Allez, on va carrément effacer l'objet Window. On le sélectionne dans MainWindow.xib et on appuie sur la touche Backspace. Si on sauvegarde et qu'on va dans XCode et qu'on compile.... Patatras! Une belle application avec un bel écran noir. Retournons dans Interface Builder. On fait apparaître la bibliothèque des objets en appuyant sur ⇧⌘L ou Tools / Library. Vous voyez tous les objets disponibles par défaut pour une application Cocoa Touch. Parcourez la liste et quand vous voyez Window, sélectionnez la et faites un drag & drop vers la fenêtre MainWidow.xib : vous venez de créer un objet de type Window qui sera accessible au démarrage. Nous allons maintenant connecter la variable window de SalutAppDelegate à cette fenêtre. Il existe trop de façons de faire les connexions. On utilisera toujours la même ici : on sélectionne l'objet d'origine, on appuie sur Ctrl, on drag vers l'objet qui nous intéresse, soit dans la fenêtre .xib, soit dans l'interface elle même, on lâche et on sélectionne la 'prise' l'outlet qui convient. Tiens, un petit screencast : Maintenant, nous allons rétablir la connexion entre viewController (la variable de SalutAppDelegate) et le le controller présent dans la fenêtre .xib . Allez y je ne vous aide pas. On est revenu dans l'état d'origine de l'interface. On va se concentrer maintenant sur deux choses : la fenêtre window, et le rapport entre le fichier source dans XCode et l'objet dans Interface builder. La fenêtre Window est la vue de base de toute votre application, la fenêtre dans laquelle toutes les vues vont s'afficher. En fait quand vous allez ajouter des objets de la librairie, vous allez ajouter des vues en cascade, et c'est pour cela que j'aime bien la vue liste : elle montre la cascade de vues. Les vues ont des supervues (les vues qui les continennent) et des sous vues (les vues qu'elles contiennent éventuellement). On ne peut toutefois pas remonter plus haut que la vue de la fenêtre : celle ci n'a pas de supervue. Cette fenêtre va nous aider à faire le lien avec la deuxième question, celle du rapport entre le code et Interface Builder. Si vous ouvrez dans XCode le code SalutAppDelegate.h, vous voyez que deux variables sont définies : @interface SalutAppDelegate : NSObject { UIWindow *window; SalutViewController *viewController; } @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) IBOutlet SalutViewController *viewController; Ce sont les deux variables que l'on retrouve dans Interface Builder. Pourquoi sont elles disponibles dans Interface Builder? C'est parce que l'on a ajouté le mot clé IBOutlet devant. Si vous rajoutez une nouvelle variable, sous la forme d'une variable mais en omettant ce IBOutlet, vous ne verrez pas la prise apparaître dans Interface Builder. C'est une erreur assez commune et qu'il m'arrive encore de faire de temps en temps. Pensez y. Les autres propriétés et variables de l'objet SalutAppDelegate ne sont pas accessibles à Interface Builder. Quand l'interface faite avec Interface Builder est 'initée', initialisée, les variables deviennent les objets représentés dans Interface Builder. Il n'est donc pas nécessaire de créer ces objets : ils sortent de leur hibernation et ils sont là, tout simplement. Pas d'alloc, d'init etc pour eux. On va retourner faire joujou avec les vues. On a vu que Window est la vue principale de l'application, celle dans laquelle on met tout. Alors ouvrez dans Interface Builder cette fenêtre et déposez y des objets avec vue : Label, Switch, TextField. etc. Sauvegardez et retournez dans XCode lancer l'application. Qu'est ce que vous obtenez? la même fenêtre grise qu'avant. Que se passe-t-il? Vos nouveaux objets sont en fait cachés par une autre vue qui vient par dessus, la vue de l'objet Salut View Controller. C'est ce que fait le code `[window addSubview:viewController.view];` dans SalutAppDelegate. Rouvrez donc Window et effacez les objets inutiles. Allons plutôt mettre des objets utiles dans la vue de SalutViewController. Dans XCode, double cliquez sur SalutViewController.xib et ajoutez un Label (UILabel) à cette fenêtre, toujours en drag & drop. Changez la taille de cet objet dans l'interface pour qu'il soit bien large et au centre. Puis dans ses attributs allez changer le texte. Ou changez le en double cliquant sur le texte Label dans l'interface. Lancez votre application. Ca y est, les objets ajoutés sont visibles! La Suite

Publié le 20 Mar 2009
Écrit par Cyril