NavigationLink - introduire un élément aléatoire

Bonjour,

Comme c’est mon premier message sur ce forum, j’en profite pour remercier Maxime pour ses cours très clairs !

Ce que je veux faire: lorsque j’appuie sur « Quizz », je souhaite ouvrir une nouvelle vue de type « WordView » avec un mot différent (aléatoire) à chaque fois.

Le code suivant ne marche pas. En cherchant sur internet, j’ai trouvé que c’était le comportement de swift, mais n’ai pas trouvé comment faire ce que je voulais !

NavigationLink(destination: WordView(aWord: vocabularyManager.wordsArray.randomElement() ?? emptyWord)) { Text("Quizz") }

Merci par avance,
Cordialement
Nicolas

C’est à dire ? Que se passe-t-il ? Ton explication n’est pas clair. Il y a deux éléments différents :

  • un tirage aléatoire d’un mot dans une liste
  • un navigationLink.

Est-ce que le tirage aléatoire ne fonctionne pas, donnant toujours le même mot ?

Ou est-ce le NavigationLink qui a un problème ?

La règle d’or du débugage est d’isoler les problèmes, de les traiter un par un.

Faire plusieurs choses dans la même ligne, c’est le début des problèmes !

Moi j’aurais tapé quelque chose comme :

if let mot = vocabularyManager.wordsArray.randomElement() {
    NavigationLink(destination: WordView(aWord:mot ) {
       Text("Quizz") }
}

On commence par tirer un mot aléatoire dans la liste, et s’il existe, on lance le NavigationLink.

Cela permet d’afficher le mot dans la console d’XCode, avant d’appeler le Link, pour vérifier que le tirage aléatoire s’est bien effectué.

 if let mot = vocabularyManager.wordsArray.randomElement() {
    print ("mot aléatoire : ", mot)
    NavigationLink(destination: WordView(aWord:mot ) {
       Text("Quizz") }
}

Tu peux aussi tester le NavigationLink en lui donnant un paramètre fixe.

    NavigationLink(destination: WordView(aWord:"Test mot aléatoire" ) {
       Text("Quizz") }

Merci pour ta réponse rapide Draken,

C’est bien l’aspect aléatoire qui ne fonctionne pas; la vue WordView contient bien un mot aléatoire la première fois que j’utilise l’application; si je reviens à la vue d’origine, et que je reclique sur « Quizz » je me retrouve avec le même mot.

Cordialement
Nicolas

Je ne connais pas randomElement ? J’ai trouvé NSRandomSubElement. On devine ce que tu veux faire, mais bon, explique un peu sur quelle syntaxe te bases-tu ? C’est du SwiftUI, non ?

C’est une fonction introduite récemment dans Swift, pour tirer aléatoirement un élément d’un tableau.

https://developer.apple.com/documentation/swift/array/2994747-randomelement

Voici l’exemple de la documentation Apple :

let names = ["Zoey", "Chloe", "Amani", "Amaia"]
let randomName = names.randomElement()!
// randomName == "Amani"

Même si moi, je n’aurais pas forcé le casting et utilisé un if let (pour éviter un plantage si le tableau est vide).

Comme je te l’ai dis plus haut, commence par vérifier le fonctionnement du tirage aléatoire.

Avec un code du genre :

 if let mot = vocabularyManager.wordsArray.randomElement() {
    print ("mot aléatoire : ", mot)
    NavigationLink(destination: WordView(aWord:mot ) {
       Text("Quizz") }
}

L’instruction print() est très pratique pour le débugage. Elle n’affecte pas le déroulement de l’application dans le simulateur ou le Device, et permet d’afficher des informations dans une fenêtre d’XCode.

J’ai la solution à ton problème. C’est basé sur la fonction .onAppear() qui s’exécute quand une vue apparait à l’écran.

import SwiftUI

// Affichage Animal aléatoire
struct SecondeVue: View {
    
    @State private var animalCourant:String = ""
    @Binding var listeAnimaux:[String]
    
    var body: some View {
        Text("Animal : \(animalCourant)")
        .onAppear(perform: {
            if let animal = self.listeAnimaux.randomElement() {
                self.animalCourant = animal
            }
        })
    }
}


struct ContentView: View {
    
    @State var liste = ["Chat", "Chien", "Souris", "lapin"]
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink("Afficher un animal au hasard",
                               destination: SecondeVue(listeAnimaux: $liste))
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Je suis trop fatigué pour ajouter les explications (1h30 du matin quand même!). Si tu ne comprends pas quelque chose, demande. Je répondrais demain.

Merci Draken !!! ça fonctionne parfaitement.

Exactement ce qu’il me fallait :grinning:

Bonne journée,
Nicolas

A ton service. Cela m’a permis d’avancer dans ma compréhension de SwiftUI. Je ne suis qu’un noob pour le moment, avec cette nouvelle manière de créer des interfaces. Je pense toujours « UIKit », alors que c’est complètement différent. Chaque exercice comme celui-ci me fait progresser.