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