NEW: Learn SwiftUI with my free YouTube video series! >>

< Previous: Choisissez un mot, n’importe quel mot : UIAlertController  

Préparer la soumission : lowercased() et IndexPath

Vous pouvez respirer à nouveau : nous en avons fini avec les closures. Je sais que ce n’était pas facile, mais une fois que vous avez compris les points essentiels, votre aventure avec Swift a vraiment beaucoup évolué.

Le code que nous allons écrire maintenant est beaucoup plus facile, parce que croyez-le ou non, nous ne sommes pas si loin de faire en sorte que ce jeu fonctionne réellement !

Tout d’abord, modifions notre code afin qu'il puisse compiler à nouveau car, à l’heure actuelle, il appelle self.submit() et nous n’avons pas encore créé cette méthode. Donc ajoutez cette nouvelle méthode quelque part dans la classe :

func submit(answer: String) {
}

C'est vrai, elle est vide - c'est assez pour que le code soit compilé proprement pour que nous puissions continuer.

Nous avons maintenant passé en revue la structure d'une closure : syntaxe de fermeture arrière, self non possédé, paramètre en cours de transmission, puis nécessité de self. pour rendre la capture claire. Nous n'avons pas vraiment parlé du contenu réel de notre fermeture, car elle ne présente pas grand chose. Pour rappel, voici à quoi ça ressemble:

let answer = ac.textFields![0]
self.submit(answer: answer.text!)

La première ligne force le déballage du tableau de champs de texte - il est optionnel car il peut ne pas en y en avoir ; nous pouvons forcer le déballage parce que nous savons que nous en avons ajouté un. La deuxième ligne extrait le texte du champ de texte et le transmet à notre méthode submit() (notre toute nouvelle méthode toute vide).

Cette méthode doit vérifier si le mot du joueur peut être composé à partir des lettres données. Elle doit vérifier si le mot a déjà été utilisé, car nous ne voulons évidemment pas de mots en double. Elle doit également vérifier si le mot est réellement un mot anglais valide, sinon l'utilisateur peut simplement taper des mots sans signification.

Si les trois vérifications sont réussies, submit() doit ajouter le mot au tableau usedWords, puis insérer une nouvelle ligne dans la vue tableau (table view). Nous pourrions simplement utiliser la méthode reloadData() pour forcer un rechargement complet, mais ce n'est pas très efficace lorsque nous modifions une seule ligne.

Commençons par créer des méthodes fictives pour les trois vérifications que nous allons effectuer : le mot est-il possible, est-il original et est-il réel ? Chacune d’elles acceptera un mot de type chaîne de caractères et renverra true ou false, mais pour l’instant nous renverrons toujours true - nous y reviendrons bientôt. Ajoutez ces méthodes maintenant:

func isPossible(word: String) -> Bool {
    return true
}

func isOriginal(word: String) -> Bool {
    return true
}

func isReal(word: String) -> Bool {
    return true
}

Avec ces trois méthodes en place, nous pouvons écrire notre premier passage à la méthode submit():

func submit(answer: String) {
    let lowerAnswer = answer.lowercased()

    if isPossible(word: lowerAnswer) {
        if isOriginal(word: lowerAnswer) {
            if isReal(word: lowerAnswer) {
                usedWords.insert(answer, at: 0)

                let indexPath = IndexPath(row: 0, section: 0)
                tableView.insertRows(at: [indexPath], with: .automatic)
            }
        }
    }
}

Si un utilisateur tape "cease" comme un mot qui peut être créé à partir de notre mot de départ "agencies", il est clair que ce mot est correct car il y a un "c", deux "e", un "a" et un "s". Mais que se passe-t-il s’il tape "Cease" ? Maintenant, le mot proposé a un C majuscule alors que "agencies" n'en a pas. Oui, c'est exact : les chaînes de caractères sont sensibles à la casse, ce qui signifie que Cease n'est pas cease, ni CeasE ou CeAsE.

La solution à cela est assez simple : tous les mots de départ sont en minuscule. Ainsi, lorsque nous vérifions la réponse du joueur, nous la mettons immédiatement en minuscule à l'aide de la méthode lowercased(). Elle est stockée dans la constante lowerAnswer parce que nous voulons l'utiliser plusieurs fois.

Nous avons ensuite trois déclarations if, l'une dans l'autre. Celles-ci sont appelées instructions imbriquées, car vous en imbriquez une dans les autres. Le bloc principal de code n'est exécuté que si les trois déclarations sont vraies (le mot est possible, le mot n'a pas encore été utilisé et il s'agit bien d'un mot réel).

Une fois que nous savons que le mot est bon, nous faisons trois choses : nous insérons le nouveau mot dans notre tableau usedWords à l'index 0. Cela signifie que nous "l'ajoutons au début du tableau" et signifie que les mots les plus récents apparaîtront en haut de la vue tableau.

Les deux points suivants sont liés : nous insérons une nouvelle ligne dans la vue tableau. Étant donné que la vue tableau (table view) tire toutes ses données du tableau (array) de mots utilisés, cela peut paraître étrange. Après tout, nous venons d'insérer le mot dans le tableau usedWords, alors pourquoi devons-nous insérer quoi que ce soit dans la vue tableau ?

La réponse est animation. Comme je l'ai dit, nous pourrions simplement appeler la méthode reloadData() et demander à la vue de recharger complètement toutes les lignes, mais cela demande beaucoup de travail supplémentaire pour un petit changement, et provoque également un saut - le mot n'était pas là, et maintenant il l'est.

Cela peut être difficile pour les utilisateurs de suivre visuellement, donc utiliser insertRows() nous permet d’indiquer à la vue tableau qu’une nouvelle ligne a été placée à un endroit spécifique du tableau afin d’animer la nouvelle cellule qui apparaît. Ajouter une cellule est également beaucoup plus facile que d'avoir à tout recharger, comme vous pouvez l'imaginer !

Il y a deux bizarreries ici qui exigent un peu plus de détails. Tout d'abord, IndexPath est un élément que nous avons brièvement vu dans le projet 1, car il contient une section et une ligne pour chaque élément de votre tableau. Comme pour le projet 1, nous n'utilisons pas de sections ici, mais le numéro de ligne doit être égal à la position dans laquelle nous avons ajouté l'élément dans le tableau (array) - la position 0, dans ce cas.

Deuxièmement, le paramètre with vous permet de spécifier comment la ligne doit être animée. Chaque fois que vous ajoutez ou supprimez des éléments d'un tableau, la valeur .automatic signifie "utilise l'animation système standard pour cette modification". Dans ce cas, cela signifie "fais glisser la nouvelle ligne à partir du haut".

Nos trois méthodes de vérification sont toujours vraies (true), quel que soit le mot saisi, mais à part cela, le jeu commence à se mettre en place. Appuyez sur Cmd + R pour essayer ce que vous avez : vous devriez pouvoir appuyer sur le bouton + et entrer des mots dans la fenêtre d'alerte.

LEARN SWIFTUI FOR FREE I wrote a massive, free SwiftUI tutorial collection, and also have a growing list of free SwiftUI tutorials on YouTube – get started today!

< Previous: Choisissez un mot, n’importe quel mot : UIAlertController  
MASTER SWIFT NOW
Buy Testing Swift Buy Practical iOS 12 Buy Pro Swift Buy Swift Design Patterns Buy Swift Coding Challenges Buy Server-Side Swift (Vapor Edition) Buy Server-Side Swift (Kitura Edition) Buy Hacking with macOS Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with Swift Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let me know!

Click here to visit the Hacking with Swift store >>