J'espère que vous n'avez pas eu trop de problèmes dans ce TP. Voici ma correction, dans laquelle je passe en revue tous les points qui auraient pu « coincer ».
Création de l'application
Dans Xcode, sélectionnez
Create a new Xcode project dans la boîte de dialogue affichée au lancement du programme. Si aucune boîte de dialogue n'est affichée, lancez la commande
New/New project dans le menu
File. Dans la boîte de dialogue
Choose a template for your new project, choisissez
Single View Application puis cliquez sur
Next. Donnez le nom
mastermind à l'application, tapez
test dans la zone de texte
Company Identifier, cochez la case
Use Storyboard et cliquez sur
Next. Choisissez un dossier pour stocker l'application et validez en cliquant sur
Create.
Au bout de quelques instants, le squelette de l'application est créé.
Définition de l'interface
Sous le dossier
mastermind, cliquez sur l'entrée
mainStoryboard.storyboard dans la barre de navigation (volet gauche de l'application). Une interface désespérément vide est affichée dans la partie droite de la fenêtre (figure suivante). Rassurez-vous, nous allons très vite la remplir.
Dans la partie supérieure droite de la fenêtre (c'est-à-dire dans la barre d'outils), au-dessus du libellé
View, cliquez sur l'icône
Hide or Show the utilities (1) et cliquez sur l'icône
Show the Object Library (2) pour faire apparaître la bibliothèque, comme indiqué à la figure suivante.
Ajoutez deux
Label, un
Text Field, un
Text View et un
Round Rect Button à l'interface, puis redimensionnez-les pour obtenir une disposition semblable à la figure suivante.
Double-cliquez tour à tour sur les différents contrôles et insérez le texte spécifié dans le tableau suivant :
| Contrôle |
Texte |
| Premier Label |
Saurez-vous trouver le nombre de quatre chiffres que j'ai choisi ? |
| Deuxième Label |
Tentez votre chance |
| Text View |
|
| Round Rect Button |
Choisir un autre nombre |
Pour mettre fin et valider la saisie d'un texte dans un contrôle, appuyez sur la touche Entrée du clavier.
Le texte saisi dans le premier Label est trop long. Comment l'afficher sur deux lignes ?
Si nécessaire, cliquez sur l'icône
Show the Attributes inspector dans la partie supérieure du volet gauche. Si vous cliquez sur le
Label, ses caractéristiques apparaissent dans le volet de l'inspecteur, comme sur la figure suivante. Sélectionnez
Word Wrap dans la liste déroulante
Line Breaks, tapez
2 dans la zone de texte
Lines et redimensionnez le contrôle pour obtenir l'effet recherché.
Pour supprimer le texte proposé par défaut dans le contrôle
TextView, cliquez dessus dans Interface Builder, sélectionnez le texte dans la zone
Text du volet de l'inspecteur, appuyez sur la touche
Suppr, puis sur la touche
Entrée du clavier.
Pour faciliter la saisie dans le Text Field, vous pouvez demander l'affichage d'un clavier numérique : cliquez sur l'icône Show the Attributes inspector dans la barre d'outils et affectez la valeur Numbers and Punctuation au paramètre Keyboard, comme indiqué à la figure suivante
Liaison des contrôles au code
Cachez la zone d'utilitaires en cliquant sur l'icône
Hide or show the Utilities (1) et affichez le code
ViewController.h en cliquant sur l'icône
Show the Assistant editor (2), comme montré à la figure suivante.
Si la zone de navigation prend trop de place sur le côté gauche de la fenêtre, vous pouvez la cacher en cliquant sur l'icône Hide or show the Navigator (dans la partie droite de la barre d'outils, au-dessus du libellé View).
Vous allez maintenant relier les contrôles de l'interface au code.
Contrôle-glissez-déposez tour à tour les contrôles
Text Field et
Text View de l'interface jusqu'au volet de code. Donnez le nom
saisie au
Text Field, et le nom
resultats au
Text View.
Si vous avez suivi mes indications, le fichier
ViewController.h doit maintenant ressembler à ceci :
Code : Objective-C | #import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextField *saisie;
@property (weak, nonatomic) IBOutlet UITextView *resultats;
@end
|
Pour terminer les liaisons, vous devez définir une action pour le contrôle
Round Rect Button. Contrôle-glissez-déposez ce contrôle juste avant l'instruction
@end. Au relâchement du bouton gauche de la souris, sélectionnez
Action dans la zone
Connection, tapez
autrenombre dans la zone de texte
Name et cliquez sur
Connect (figure suivante).
La ligne suivante est ajoutée au code :
Code : Objective-C | - (IBAction)autrenombre:(id)sender;
|
Sauvegardez votre projet avec la commande
Save dans le menu
File.
Juste histoire de souffler un peu, vous pouvez cliquer sur l'icône
Run dans la barre d'outils et savourer votre travail. Le résultat affiché devrait être semblable à la figure suivante.
Cliquez sur
Stop pour revenir à la dure réalité : vous devez maintenant écrire le code qui donnera vie à l'application !
Avant de commencer, cliquez sur
ViewController.h dans le volet de navigation et définissez la variable d'instance
nombreChoisi de type
int pour mémoriser le nombre choisi par le device. Le fichier d'en-têtes doit maintenant ressembler à ceci :
Code : Objective-C | @interface ViewController : UIViewController
{
int nombreChoisi;
}
@property (weak, nonatomic) IBOutlet UITextField *saisie;
@property (weak, nonatomic) IBOutlet UITextView *resultats;
- (IBAction)autrenombre:(id)sender;
@end
|
Je vous sens vraiment impatients de faire fonctionner l'application. Alors, passons sans plus attendre à l'écriture du code.
Écriture du code
Si nécessaire, affichez la zone de navigation en cliquant sur l'icône
Hide or show the Navigator, dans la partie droite de la barre d'outils, au-dessus du libellé
View.
Cliquez sur
mastermindViewController.m dans la zone de navigation. Le code généré par Xcode est de taille respectable. Il contient les différentes méthodes utilisées par l'application :
Code : Objective-C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 | //Pour une meilleure lisibilité, j'ai supprimé les commentaires ajoutés automatiquement au début du fichier par Xcode
#import "ViewController.h"
@implementation ViewController
@synthesize saisie;
@synthesize resultats;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setSaisie:nil];
[self setResultats:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)autrenombre:(id)sender {
}
@end
|
En examinant les dernières lignes, vous reconnaissez certainement la partie déclarative liée à l'action sur le contrôle
Round Rect Button :
Code : Objective-C | - (IBAction)autrenombre:(id)sender {
}
|
Quelques lignes plus haut, la méthode
viewDidLoad va vous permettre d'initialiser l'application :
Code : Objective-C | - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
|
Mais pourquoi serait-il nécessaire d'initialiser l'application me direz-vous ? Eh bien… pour choisir le nombre à découvrir !
Tirage aléatoire du nombre à découvrir
Ajoutez la ligne que nous avons vue plus haut, après
[super viewDidLoad]; :
Code : Objective-C | nombreChoisi = arc4random() % 9000 + 1000;
|
L'application sait maintenant tirer au hasard un nombre compris entre
1000 et
9999.
Traitement suite à la proposition d'un nombre
Lorsque le joueur a saisi un nombre de quatre chiffres, il appuie sur la touche
Return pour valider la saisie. Le clavier doit alors disparaître de l'écran et le nombre entré doit être comparé au nombre à découvrir.
Pour ce faire, il est nécessaire de capturer l'événement « appui sur la touche
Return » et de le relier à une méthode afin d'effectuer les traitements nécessaires.
Dans un premier temps, commencez par définir la méthode
saisieReturn dans le fichier d'en-têtes. Cliquez sur
ViewController.h dans le volet de navigation et entrez cette ligne, juste au-dessus du
@end final :
Code : Objective-C | - (IBAction)saisieReturn :(id)sender;
|
Le fichier d'en-têtes doit maintenant ressembler à ceci :
Code : Objective-C 1
2
3
4
5
6
7
8
9
10
11
12
13 | #import <UIKit/UIKit.h>
@interface ViewController : UIViewController
{
int nombreChoisi;
}
@property (weak, nonatomic) IBOutlet UITextField *saisie;
@property (weak, nonatomic) IBOutlet UITextView *resultats;
- (IBAction)autrenombre:(id)sender;
- (IBAction)saisieReturn :(id)sender;
@end
|
Pour écrire le code qui efface le clavier de l'écran, cliquez sur
ViewController.m dans le volet de navigation et définissez la méthode
saisieReturn comme suit :
Code : Objective-C | -(IBAction)saisieReturn:(id)sender
{
[sender resignFirstResponder];
}
|
La méthode
resignFirstResponder efface le clavier. C'est aussi simple que cela !
N'essayez pas d'exécuter l'application : vous devez auparavant relier l'événement « appui sur la touche
Retour » à la méthode
saisieReturn.
Pour cela, sélectionnez l'entrée
MainStoryboard.storyboard dans la zone de navigation, affichez le volet des utilitaires en cliquant sur
Hide or show the Utilities dans la barre d'outils, puis cliquez sur
Show the Connections inspector, dans la partie supérieure. Cliquez sur le contrôle
Text Field dans la zone d'édition pour le sélectionner. Sous
Sent Events, repérez le rond à droite de l'événement
Did End On Exit et déplacez-le sur l'icône
View Controller, dans la partie inférieure de la zone d'édition. Au relâchement du bouton gauche de la souris, deux choix vous sont proposés :
autreNombre et
saisieReturn (figure suivante). Cliquez sur
saisieReturn. Ainsi, la méthode
saisieReturn sera exécutée lorsque l'utilisateur appuiera sur la touche
Return du téléphone.
Vous pouvez maintenant exécuter l'application et vérifier que l'appui sur la touche
Return dissimule le clavier.
Il est temps maintenant d'écrire le code relatif au traitement du nombre choisi par le joueur.
Cliquez sur
ViewController.m dans la zone de navigation et complétez la méthode
saisieReturn comme suit :
Code : Objective-C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | -(IBAction)saisieReturn:(id)sender
{
[sender resignFirstResponder];
int bienPlace = 0;
int charIndex; //Index de boucle pour parcourir tous les caractères des chaînes à comparer
unichar testChar1, testChar2; //Les caractères à comparer : testChar1 dans le nombre proposé, testChar2 dans le nombre à trouver
for (charIndex = 0; charIndex < 4; charIndex++)
{
testChar1 = [saisie.text characterAtIndex:charIndex];
testChar2 = [[NSString stringWithFormat:@"%d", nombreChoisi] characterAtIndex:charIndex];
if (testChar1 == testChar2)
bienPlace++;
}
resultats.text = [NSString stringWithFormat:@"%@%@%d%@%@", saisie.text, @" : Bien placés : ", bienPlace, @"\r", resultats.text];
if (bienPlace == 4)
resultats.text = [NSString stringWithFormat:@"%@%d", @"Bravo, le résultat était ", nombreChoisi];
}
|
Examinons un peu ce code ensemble.
Comme il a été dit précédemment, la ligne 3 supprime le clavier de l'écran. Jusque-là, tout va bien !
Le bloc d'instructions suivant (lignes 4 à 13) compare le nombre entré par le joueur au nombre à découvrir. Les premières lignes déclarent plusieurs variables :
- la variable entière bienPlace est définie et initialisée à 0 :
int bienPlace = 0;
- la variable entière charIndex est définie mais non initialisée :
int charIndex;
- il en va de même pour les variables unichar testChar1 et testChar2 :
unichar testChar1, testChar2;
La comparaison des quatre chiffres se fait dans une boucle
for, en utilisant la variable
charIndex comme index de boucle :
Code : Objective-C | for (charIndex = 0; charIndex < 4; charIndex++)
|
À l'intérieur de la boucle, la première instruction s'intéresse à la saisie du joueur. Elle isole le caractère d'index
charIndex et le stocke dans la variable
unichar testChar1 :
Code : Objective-C | testChar1 = [saisie.text characterAtIndex:charIndex];
|
La deuxième instruction fait de même, mais sur le nombre tiré aléatoirement. L'instruction est plus complexe, car le nombre choisi aléatoirement est un
int et non un
NSString. Il est donc nécessaire de le convertir en
NSString avant de procéder à l'extraction :
Code : Objective-C | testChar2 = [[NSString stringWithFormat:@"%d", nombreChoisi] characterAtIndex:charIndex];
|
Le premier message convertit l'
int nombreChoisi en un
NSString :
Code : Objective-C | [NSString stringWithFormat:@"%d", nombreChoisi]
|
On extrait de l'objet ainsi obtenu le caractère qui se trouve à l'emplacement
charIndex (
characterAtIndex:charIndex) et on mémorise ce caractère dans la variable
testChar2 (
testChar2 =).
Il ne reste plus qu'à comparer
testChar1 à
testChar2 et à incrémenter la variable
bienPlace si ces deux variables sont égales :
Code : Objective-C | if (testChar1 == testChar2)
bienPlace++;
|
Une fois que les quatre chiffres ont été testés, il faut afficher le résultat dans le contrôle
TextView. C'est le rôle de l'instruction suivante :
Code : Objective-C | resultats.text = [NSString stringWithFormat:@"%@%@%d%@%@", saisie.text, @" : Bien placés : ", bienPlace, @"\r", resultats.text];
|
On utilise pour cela une chaîne formatée (
[NSString stringWithFormat: …]). Examinons le format de la chaîne affichée :
Code : Objective-C
En comptant le nombre de
%, vous pouvez facilement déduire que cette chaîne est composée de cinq éléments. De gauche à droite, deux chaînes (
%@), un nombre décimal (
%d) et deux chaînes (
%@). Ces éléments sont les suivants :
- la valeur saisie par le joueur, saisie.text ;
- le texte « Bien placés : » ;
- la valeur décimale bienPlace, convertie en une chaîne de caractères ;
- un saut de ligne \r ;
- les différentes informations précédemment affichées dans le contrôle TextView.
La dernière instruction teste si la partie est terminée :
Code : Objective-C | if (bienPlace == 4)
resultats.text = [NSString stringWithFormat:@"%@%d", @"Bravo, le résultat était ", nombreChoisi];
|
Si le nombre de caractères bien placés est égal à
4 (
if (bienPlace == 4)), cela signifie que le nombre entré est égal au nombre à découvrir. Dans ce cas, un message est affiché dans le contrôle
TextView resultats (
resultats.text =). Ici encore, nous utilisons une chaîne formatée (
[NSString stringWithFormat: …]). Comme vous pouvez le voir, le texte affiché est composé d'une chaîne et d'un nombre entier : le texte « Bravo, le résultat était », suivi du nombre à découvrir.
Tirage aléatoire d'un autre nombre
Pour terminer ce programme, il reste à écrire le code relatif à l'appui sur le bouton
Choisir un autre nombre. Rassurez-vous, cette tâche vous paraîtra on ne peut plus simple après ce que vous venez de vivre !
L'entrée
ViewController.m étant sélectionnée dans le volet de navigation, déplacez-vous dans la partie inférieure du code et complétez la méthode
autrenombre comme suit :
Code : Objective-C | - (IBAction)autrenombre:(id)sender
{
nombreChoisi = arc4random() % 9000 + 1000;
resultats.text = [NSString stringWithFormat:@"%@", @"J'ai choisi un nouveau nombre\r"];
}
|
La première instruction est identique à celle qui a déjà été utilisée pour tirer un nombre aléatoire. Elle choisit un nombre compris entre
1000 et
9999 et le stocke dans la composante
text de l'objet label
nombreChoisi :
Code : Objective-C | nombreChoisi = arc4random() % 9000 + 1000;
|
La deuxième instruction affiche le message « J'ai choisi un nouveau nombre » dans le contrôle
TextView :
Code : Objective-C | resultats.text = [NSString stringWithFormat:@"%@", @"J'ai choisi un nouveau nombre\r"];
|
L'application est entièrement fonctionnelle. Cliquez sur
Run et amusez-vous bien !
Le code complet
Je vous mets ici le code complet de l'application.
ViewController.h
Code : Objective-C 1
2
3
4
5
6
7
8
9
10
11
12
13 | #import <UIKit/UIKit.h>
@interface ViewController : UIViewController
{
int nombreChoisi;
}
@property (weak, nonatomic) IBOutlet UITextField *saisie;
@property (weak, nonatomic) IBOutlet UITextView *resultats;
- (IBAction)autrenombre:(id)sender;
- (IBAction)saisieReturn :(id)sender;
@end
|
ViewController.m
Code : Objective-C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 | #import "ViewController.h"
@implementation ViewController
@synthesize saisie;
@synthesize resultats;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
nombreChoisi = arc4random() % 9000 + 1000;
}
- (void)viewDidUnload
{
[self setSaisie:nil];
[self setResultats:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)autrenombre:(id)sender
{
nombreChoisi = arc4random() % 9000 + 1000;
resultats.text = [NSString stringWithFormat:@"%@", @"J'ai choisi un nouveau nombre\r"];
}
-(IBAction)saisieReturn:(id)sender
{
[sender resignFirstResponder];
int bienPlace = 0;
int charIndex;
unichar testChar1, testChar2;
for (charIndex = 0; charIndex < 4; charIndex++)
{
testChar1 = [saisie.text characterAtIndex:charIndex];
testChar2 = [[NSString stringWithFormat:@"%d", nombreChoisi] characterAtIndex:charIndex];
if (testChar1 == testChar2)
bienPlace++;
}
resultats.text = [NSString stringWithFormat:@"%@%@%d%@%@", saisie.text, @" : Bien placés : ", bienPlace, @"\r", resultats.text];
if (bienPlace == 4)
resultats.text = [NSString stringWithFormat:@"%@%d", @"Bravo, le résultat était ", nombreChoisi];
}
@end
|