Calculs dans un Array et TableView

Bonjour à tous,

je suis en train de développer une petite app (encore et toujours) de calculs de temps, vitesse, etc. pour mes élèves qui doivent préparer leurs séances de courses en EPS au lycée.

Pour leur faciliter la tâche, cette app leur permettrai de créer des intervalles avec un temps à respecter de courses en fonctions des critères choisis: vitesse, intensité, distance et récupération via des PickerView). Ce que je voudrais c’est qu’au fur et à mesure qu’ils ajoutent un intervalle, le total de temps de la séance s’affiche. Et là, je bloque. Voici l’interface:

L’encadré rouge et le temps total sur la capture est le calcul que je voudrais faire.
En cherchant, la piste serait de créer un tableau à partir des temps de courses calculés et crées dans la tableview. Je n’arrive pas a récupérer les temps dans un tableau. Je pense que c’est via l’opérateur .map si j’ai bien compris.

Au niveau des viewControllers, je me suis calé sur le cours de Maxime.
J’ai un ViewControler avec les PickerView et la TableView sur fond noir comme déposé juste avant et j’ai un Courses.Manager dans lequel j’ai initialisé le tableau des courses _coursesList:

class CoursesManager {
var _coursesList:[String]

init() {
    _coursesList = []
    
}

func getCoursesCount() -> Int{
    return _coursesList.count
}

func getCourses(atIndex index:Int) -> String {
    return _coursesList[index]
}

func addCourse(withText text:String) -> Int? {
    let newIndex:Int?
    if text.count > 0 {
    _coursesList.append(text)
        newIndex = _coursesList.count - 1
    } else {
        newIndex = nil
    }
    return newIndex
}
    
func removeCourse(atIndex index:Int){
    _coursesList.remove(at: index)
}

}

Finalement, je voudrais pouvoir récupérer un tableau des temps calculés (en gras et en blanc à gauche sous les PickerView) pour en faire une somme. J’y ajouterai les temps de récupération pour que le temps de séance soit total.

Merci ce votre aide. :wink:

Hello, Jean-Charles.

Tu reviens au développement ? Bonne chose.

Il est facile d’additionner toutes les valeurs contenues dans un tableau.
On peut le faire de plusieurs manières. La solution classique est d’utiliser une boucle pour lire chaque valeur et l’additionner au total.
De manière plus moderne, on peut utiliser l’opérateur Swift .reduce() pour réaliser une opération mathématique sur l’ensemble du tableau, en une seule ligne.

Voilà comment je ferais, moi :

let lesTemps = [12, 6, 21, 9]
let total = lesTemps.reduce(0, +)
print ("Temps total : ", total)

Le problème c’est que je le fais sur un tableau NUMERIQUE. Alors que tu utilises des chaînes de caractères pour stocker tes temps. Drôle d’idée …

Si tu veux faire des calculs, des tris, des comparaisons sur tes données elles doivent être sous forme NUMERIQUE !


Dans un autre ordre d’idée, ton application n’est guère conforme au standard graphique iOS. Le fond noir n’est pas une bonne idée …

Salut Draken,

oui, j’essaie d’y revenir mais le temps me manque cruellement! Mais je m’accroche.

J’avais bien vu l’opérateur .reduce mais avant de l’utiliser, ma problématique est de recréer un tableau comportant des données rentrées dans des labels dans une CustomtableView. Je sens bien qu’il y a un truc qui je n’ai pas bien saisi au niveau de l’articulation entre le manager qui crée un tableau et les fonctions j’ajout et le viexwwController.
Lorsque je crée une nouvelle ligne dans ma tableView, ça crée un nouvelle ligne dans le tableau de mon Manager normalement.
Dans mon viewController j’ai:

@IBAction func addToList(_ sender: UIButton) {
if let intervalText = timePassageLbl.text,
let intervalIndex = _coursesManager.addCourse(withText: intervalText) {
ui_tableViewCourses.insertRows(at: [IndexPath(row: intervalIndex, section: 0)], with: .automatic)
}
}

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    print("interval N°\(_coursesManager.getCoursesCount())")
    return _coursesManager.getCoursesCount()
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellCourse", for: indexPath) as! ListeCoursesTableViewCell
    cell.labelCourses.text = _coursesManager.getCourses(atIndex: indexPath.row)
    cell.purcentLbl.text = "\(_purcentInitChoosed)%"
    cell.speedLbl.text = "\(_speedChoosed) km/h"
    cell.kiloTimeLbl.text = ("\(_calculManager.returnTime(temps: _kmTime)) au kilo")
    cell.distanceLbl.text = "\(_distanceChoosed)m"
    cell.restLbl.text = "\(_restInitChoosed)"

    return cell
}

Comment puis-je créer un tableau comportant ce qu’il y a dans un des labels de la custom TableView?

Pour le fond noir, je voulais rester sur les canons de l’app chrono et activité d’iOS. :wink:

L’architecture de ton système est mauvais. Je n’ai pas le temps de t’expliquer cet après-midi. Je te répond ce soir ou demain.

1 « J'aime »

Ce que j’adore avec Draken, c’est que c’est toujours clair et net! :joy:

Au moins, je sais! Merci de ton temps passé pour nous répondre!

Je pense qu’il te faut un Objet Course du style :

class Course {
    private var distance: Int
    private var vitesse: Double
    private var intensite: Int
    private var recuperation: Int
    
    init(distance: Int, vitesse: Double, intensite: Int, recuperation: Int) {
        self.distance = distance
        self.vitesse = vitesse
        self.intensite = intensite
        self.recuperation = recuperation
    }
    
    public func getDistance() -> Int {
        return distance
    }
    
    public func getVitesse() -> Double {
        return vitesse
    }
    
    public func getIntensite() -> Int {
        return intensite
    }
    
    public func getRecuperation() -> Int {
        return recuperation
    }
}

Et effectivement un [Course] comme tu as fais ton manager.
Ainsi, chaque course tu peux récupérer individuellement les données pour le table view.

Et pour avoir un total, .map() ou for() sur le tableau.

A savoir que dans mon exemple j’ai pris le parti d’avoir un temps de récupération en Int, pour y stocker par exemple des secondes.

Si tu souhaites avoir le temps en minute, un truc du style fonctionne a peu près :

func getRecuperationMinute(recuperation: Int) -> String {
    return String(recuperation / 60) + ":" + String(recuperation % 60)
}
1 « J'aime »

Bonjour Gaveline,
tout ça dans le même manager?

Du coup, à chaque fois qu’est crée une course dans CoursesList, cela créerait un nouvel objet Course?

L’architecture de ton application ne respecte pas le paradigme MVC, d’où ton problème.

Selon le MVC un écran est composé de trois partie :

  • un Modèle qui contient toutes les informations utilisateurs
  • Une Vue (l’interface) qui n’est que le reflet du Modèle et ne doit contenir aucune information
  • Un Contrôleur qui gère les interactions entre le Modèle et la Vue

L’interaction type est :

  • l’utilisateur agit sur un contrôle graphique de la Vue, qui prévient le Contrôleur
  • le Contrôleur modifie l’état du Modèle en fonction de l’action de l’utilisateur
  • le Contrôleur force la Vue à se redessiner pour refléter les modifications du Modèle

Cela assure une totale indépendance entre le Modèle et la Vue.

Pour en revenir à ton problème, tu dois avoir un Modèle contenant tes informations. Comme le recommande @gaveline, il faut stocker tes données dans une classe spécialisée, comme celle-ci :

class UneCourse {
    var distance     : Int
    var vitesse      : Double
    var intensite    : Int
    var recuperation : Int
    
    init (distance     : Int,
          vitesse      : Double,
          intensite    : Int,
          recuperation : Int)
    {
        self.distance     = distance
        self.vitesse      = vitesse
        self.intensite    = intensite
        self.recuperation = recuperation
    }
}

Les courses doivent êtres stockées dans le Modèle, en l’occurence un simple tableau d’objets

var listeDesCourses = [UneCourse]()

Chaque nouvelle course doit être stockée dans le Modèle

    let course = UneCourse(distance: 550,
                           vitesse: 11.5,
                           intensite: 110,
                           recuperation: 2.0)
    
    listeDesCourses.append(course)

Pour mettre à jour ta TableView tu as juste besoin de lire la taille du tableau listeDesCourses pour connaître le nombre d’éléments, avant d’ajouter une nouvelle cellule à la fin.


Lorsque la TableView a besoin de créer une nouvelle cellule, elle doit consulter le Modèle pour connaitre les informations.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellCourse", for: indexPath) as! ListeCoursesTableViewCell
    /*
    cell.labelCourses.text = _coursesManager.getCourses(atIndex: indexPath.row)
    cell.purcentLbl.text = "\(_purcentInitChoosed)%"
    cell.speedLbl.text = "\(_speedChoosed) km/h"
    cell.kiloTimeLbl.text = ("\(_calculManager.returnTime(temps: _kmTime)) au kilo")
    cell.distanceLbl.text = "\(_distanceChoosed)m"
    cell.restLbl.text = "\(_restInitChoosed)"
    */

    // index de la Course
    let indexCourse = indexPath.row
    // lecture course
    let laCourse = listeDesCourse[indexCourse]

    // Lecture des données
    let distance = laCourse.distance
    let vitesse = laCourse.vitesse
    .....
   
    // Affichage des données dans les labels de la cellule personnalisée
    ....

    return cell
}

(code non testé, tapé de tête)


Tu peux ensuite ajouter d’autres fonctions manipulant le Modèle, comme par exemple additionner toutes les temps.

EDIT : Exemple d’une fonction additionnant toutes les distances contenues dans le Modèle

func compterLesDistances() -> Int {
    var distanceTotale = 0
    
    for course in listeDesCourses {
        distanceTotale += course.distance
    }
    return distanceTotale
}

C’est une boucle simple, j’ai préféré ne pas utiliser les fonctions sophistiqués de swift pour ne pas t’encombrer l’esprit avec une nouvelle syntaxe compliqué.

Oui … Tu dois conserver toutes les courses en mémoire.

La tableView n’archive PAS LES INFORMATIONS AFFICHEES ! On a l’impression que les tableView peuvent manipuler un grand nombre de cellules, mais c’est une illusion. Chaque cellule est une vue graphique prenant de la place en mémoire, beaucoup de place… C’est pourquoi la tableView ne crée que le nombre de cellules nécessaires à l’affichage sur l’écran.

Prenons le cas d’une liste de 30 éléments, associée à une petite tableView ne pouvant en afficher que 5 à la fois. Elle ne crée que 6 CELLULES (les 5 visibles, plus une supplémentaire, pour assurer un scrolling fluide).

Chaque fois qu’une cellule sort de l’écran, elle est recyclée. iOS redessine par dessus d’autres données pour donner l’impression d’une nouvelle cellule, alors que c’est toujours la même …

Pour que cela fonctionne correctement, la tableView a besoin de pouvoir demander au viewController, à n’importe quel moment, les informations d’une cellule pour la recréer. D’où le besoin de la dataSource, qui consulte les données du Modèle pour alimenter la tableView en informations.

Cela peut sembler compliqué, mais cela permet d’avoir des tableView très grandes, avec une minimum de consommation mémoire et de ralentissements à l’affichage.

Ok. Je vais essayer de manipuler tout ça ce week-end! Je DOIS comprendre ce fonctionnement car c’est la base de la plupart des app dont j’ai besoin.
Merci pour ces explications détaillées.m. Je reviendrai vers vous car je vais sûrement avoir des questions! :hugs:
Et bien sûr, je vais réfléchir aux couleurs de l’interface graphique! :kissing_smiling_eyes:

Bonjour,j’ai regardé tout ça et j’ai une difficulté concernant l’ajout d’une nouvelle course.
J’ai crée 2 class différentes avec 2 fichiers SWIFT différents:

class LaCourse {
    var distance     : Int
    var vitesse      : Double
    var intensite    : Int
    var recuperation : Int
    var tempsPassage : Double
    
    init (distance: Int, vitesse: Double, intensite: Int, recuperation: Int, tempsPassage: Double)
    {
        self.distance     = distance
        self.vitesse      = vitesse
        self.intensite    = intensite
        self.recuperation = recuperation
        self.tempsPassage = tempsPassage
    }
    
    }

puis un ObjetCourseManager pour gérer le nombre, l’index et l’ajout des courses:

class ObjectCoursesManager {
    
        var _listeDesCourses = [LaCourse]()

// nombre de courses
    func getCoursesCount() -> Int{
            return _listeDesCourses.count
        }
    
// index de la Course
        func getCourses(atIndex index:Int) -> LaCourse {
            return _listeDesCourses[index]
        }
    
//    ajouter une course
    func addCourse() {
            _listeDesCourses.append(LaCourse)

    }
        func removeCourse(atIndex index:Int){
            _listeDesCourses.remove(at: index)
        }

}

Mais cela ne fonctionne pas. Il vois bien qu’il faut ajouter un objet de type objet, non?

Cela ne risque pas de fonctionner, si tu ne communiques pas la nouvelle course à ton manager.

Change :

func addCourse() {
_listeDesCourses.append(LaCourse)
}

Par :

func addCourse(course :LaCourse) {
_listeDesCourses.append(course)
}

Ok. J’étais pas loin dans mes tentatives.

j’ai modifié dans le controleur:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cellCourse", for: indexPath) as! ListeCoursesTableViewCell
            
            // index de la Course
            let indexCourse = indexPath.row

            // lecture course
            let laCourse = _ObjectCoursesManager._listeDesCourses[indexCourse]

            // Lecture des données
            _distanceChoosed* = laCourse.distance
            _speedChoosed* = laCourse.vitesse

            // affectations dans la customCell
            cell.speedLbl.text = "\(_speedChoosed) km/h"
 
            cell.distanceLbl.text = "\(_distanceChoosed)m"
   
            return cell
        }

* se sont mes variables auxquelles je passe le résultat des choix via les PickerView. Normalement ça devrait être bon (?).

Désormais, c’est ici que je bloque sur la fonction ajouter à la tableView:
Dans le cours de Maxime:

@IBAction func addToList(_ sender: UIButton) {
        if let intervalText = timePassageLbl.text,
        let intervalIndex = _coursesManager.addCourse(withText: intervalText) {
                ui_tableViewCourses.insertRows(at: [IndexPath(row: intervalIndex, section: 0)], with: .automatic)
            }
    }

Si je transpose, ça ferait:
si on peut créer un un objet Course, alors j’hérite de la fonction func addObjectCourse de mon ObjectCoursesManager et alors on insert une nouvelle ligne dans la tableView.

    @IBAction func addToList(_ sender: UIButton) {
          if let objetCourse = Lacourse, 
               let objetCourseIndex = _ObjectCoursesManager.addObjectCourse(course:objetCourse){
            ui_tableViewCourses.insertRows(at: [IndexPath(row:objetCourseIndex,section: 0)], with: .automatic)
            }
        }

je n’arrive pas à initialiser objetCourse.

Tu dois créer l’objet course en lui passant les paramètres courant lus dans les pickersView.

let distance =        // .. à lire dans le pickerView
let vitesse =         // .. idem
let intensité =       // .. idem
let recuperation =    // .. idem
let tempsPassage =    // .. idem

// Création objet
let objetCourse = LaCourse(distance:distance,
                           vitesse:vitesse,
                           intensite:intensite,
                           recuperation: recuperation,
                           tempsPassage:tempsPassage)

Ton IBAction doit ressembler à ça :

@IBAction func addToList(_ sender: UIButton) {

   // Lecture des paramètres dans les pickersView
   // .....
   // Création de l'objet
   let objetCourse = LaCourse(distance:distance,
                              vitesse:vitesse,
                              intensite:intensite, 
                              recuperation: recuperation, 
                              tempsPassage:tempsPassage)

   // Ajout de l'objet dans la liste
   // ...
   
  // Création d'une nouvelle cellule à la fin de la tableView
  // ... 
}

Ok. J’ai modifié mais j’ai encore une erreur:

 @IBAction func addToList(_ sender: UIButton) {
        let distancePV = _distanceChoosed
        let speedPV = _speedChoosed
        let intensitePV = _purcentInitChoosed
        let recupPV = _restInitChoosed
        let timePassagePV = _timeBaseRounded
        
        let objetCourse = LaCourse(distance: distancePV, vitesse: speedPV, intensite: intensitePV, recuperation: recupPV, tempsPassage: timePassagePV)
        
        let objetCourseIndex = _ObjectCoursesManager.addObjectCourse(course:objetCourse){
            ui_tableViewCourses.insertRows(at: [IndexPath(row:objetCourseIndex,section: 0)], with: .automatic)
        }
    }

message d’erreur: variable used within own initial value. C’est au niveau de (row:objetCourseIndex

Pourtant il s’agit bien de créer un nouvel index dans la tableView qui correspond au nouvel objet crée. On insert la ligne dont le numéro de ligne correspond au numéro de ligne dans le tableau d’objetCourses?

Le message d’erreur indique que tu utilises une variable sans lui avoir donné une valeur. Je ne sais pas d’où cela peut provenir, sans voir le reste du code.

J’ai commencé à taper un exemple hier soir, pour te montrer comment moi j’aurais écrit le code. Je le met en ligne dés qu’il sera finalisé, avant midi.

La manipulation des index est compliqué pour un novice. Il y a une manière plus simple d’actualiser une tableView : utiliser la méthode .reload().

Tu ajoutes l’objet Course au tableau servant de dataSource. Puis tu appelles .reload(), pour indiquer à la tableView que sa dataSource a été modifiée, et qu’il faut reconstruire l’affichage.

listeDesCourses.append(course)        
tableView.reloadData()

C’est simple et efficace.

Voici ma version (simplifiée) de ton application. Il n’y a qu’un paramétre : la distance.

Le design est basique, avec des cellules standard pour la tableView.

Le code source :

//
//  ViewController.swift
//  BidaultTableau
//
//  Created by Patrick Leclercq on 09/10/2018.
//  Copyright © 2018 patrick leclercq. All rights reserved.
//

import UIKit


class UneCourse {
    var distance : Int
    
    init(distance:Int) {
        self.distance = distance
    }
}

class ViewController:   UIViewController,
                        UIPickerViewDelegate,
                        UIPickerViewDataSource,
                        UITableViewDelegate,
                        UITableViewDataSource
{
    @IBOutlet weak var pickerView:          UIPickerView!
    @IBOutlet weak var label:               UILabel!
    @IBOutlet weak var tableView:           UITableView!
    @IBOutlet weak var labelDistanceTotale: UILabel!
    
    // dataSource (Modèle) pour la tableView
    private var listeDesCourses = [UneCourse]()
    
    // Contenus du pickerView
    let dataSourcePickerView = [
        "100 mètres",
        "200 mètres",
        "500 mètres",
        "750 mètres",
        "12.000 métres"]
    
    // Stockage des distances (Int)
    let listeDesDistancesPickerView = [
        100, 200, 500, 750, 12000]
    
    // stockage sélection courante du pickerView
    var indexPickerView  = 0
    var distanceCourante = 0
    
    // Distance totale
    var distanceTotale   = 0
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        initPickerView()
        tableView.delegate   = self
        tableView.dataSource = self
        
        actualiserInterface()
        
    }
    
    // Initialisation du PickerView
    // et de la variable distanceCourante
    func initPickerView() {
        pickerView.dataSource = self
        pickerView.delegate   = self
        
        // La distance initiale est celle
        // de la première cellule du pickerView
        distanceCourante = listeDesDistancesPickerView[0]
    }
    
    // Centralisation de la mise à jour
    // du contenu de l'interface
    func actualiserInterface() {
        // Affichage Distance Courante
        label.text = String(distanceCourante) + " mètres"
        
        // Affichage distance totale
        labelDistanceTotale.text = "Distance totale : " + String(distanceTotale) + " mètres"
    }
    
    // ---------------------------------------
    // Gestion du pickerView
    // Nombre de colonnes (une seule)
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    // Nombre d'éléments
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return dataSourcePickerView.count
    }
    
    // Lecture d'une ligne du PickerView à partir de son index
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return dataSourcePickerView[row]
    }
    
    // Traitement de l'événement survenant
    // quand le PickerView change de valeur
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        let index = row
        distanceCourante = listeDesDistancesPickerView[index]
        actualiserInterface()
    }
    
    // ---------------------------
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return listeDesCourses.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        // Création (ou recyclage) de la cellule
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        
        // Lecture des informations du Modèle
        let course = listeDesCourses[indexPath.row]
        // Extraction des informations du Modèle
        let distance = course.distance
        
        // On écrit dans la cellule
        cell.textLabel?.text = String(distance)
        return cell

    }
    
    // Boucle pour compter les distances
    // stockées dans le tableau listeDesCourses
    func compterLesDistances() -> Int {
        var distanceTotale = 0
        
        for course in listeDesCourses {
            distanceTotale += course.distance
        }
        return distanceTotale
     
        // Version "évoluée" du comptage
        // utilisant les nouvelles fonctions de Swift 4.0
        // return listeDesCourses.compactMap({$0.distance}).reduce(0, +)
    }
           
    // Création d'une nouvelle cellule à la fin de la tableView
    func creerNouvelleCelluleTableView() {
        // Lecture du nombre de Courses enregistrés en mémoire
        let nbCourses = listeDesCourses.count
        // Calcul de l'index de la nouvelle Cellule
        // (il faut retirer -1 puisque les numérotation des Index)
        // (commencent à la valeur 0 - une source interminable)
        // (d'erreurs pour les novices depuis l'invention de l'informatique)
        let indexNouvelleCellule = nbCourses - 1
        // Calcul du VERITABLE Index de la cellule dans la tableView
        // (la position d'une cellule dans la tableView est déterminée)
        // (par sa rangée (row) et sa section.)
        // (Il n'y a qu'une seule section ici, donc toujours égale à 0)
        // (Encore le fichu probléme de numération des objets à partir de 0)
        let indexPath = IndexPath(row: indexNouvelleCellule, section: 0)
        // Insertion de la cellule dans la tableView
        tableView.insertRows(at: [indexPath], with: .automatic)
    }
    
    
    @IBAction func actionMemoriserDistance(_ sender: Any) {
        // Création d'un objet à partir de
        // la distance courante du pickerView
        let course = UneCourse(distance: distanceCourante)
        // On mémorise la course
        listeDesCourses.append(course)
        
        // On crée une nouvelle cellule à la fin de la tableView
        // La tableView vas alors automatiquement lire sa
        // dataSource (tableau ListeDesCourse) pour savoir quoi mettre
        // dans la nouvelle cellule
        creerNouvelleCelluleTableView()
        
        // ASTUCE : Il est compliqué d'ajouter une nouvelle cellule
        // à la tableView, en raison des calculs d'index.
        // On peut remplacer l'appel à creerNouvelleCelluleTableView()
        // par un reload de la tableView
        // -----------------
        // Avantage : une seule ligne de code
        // Inconvénient : c'est une opération globale forçant
        // la tableView à recharger les données
        // et RECREER toutes les cellules VISIBLES
        // (c'est insignifiant pour une application simple comme celle-ci)
        
        // tableView.reloadData()
        
        // Mise à jour de la distance totale
        distanceTotale = compterLesDistances()
        // Mise à jour interface graphique
        actualiserInterface()

    }
    
}

C’est un peu brut de décoffrage. Je n’ai pas le temps de taper des explications détaillées maintenant, mais j’ai mis des commentaires dans le code.

Cela fonctionne, comme le montre la copie d’écran (Xcode 10 - Swift 4.1 - Simulateur iPhone 8+)

Des questions ?

EDIT : J’ai supprimé quelques trucs inutiles dans le code. Si tu as reçu la première version du code par mail avec la notification automatique du serveur, utilise le code du post, et non celui du mail.

1 « J'aime »

YES!

Merci beaucoup, comme à chaque fois Draken… L’explication pas à pas m’a permis de croiser avec le cours de Maxime et j’ai mieux compris les étapes de la création de l’index. Je n’ai pas essayé “d’externaliser” ça comme dans le cours dans le manager mais peu importe. J’ai pigé l’affectation dans l’objet puis le passage des données à la TableView, puis l’affichage.
Cool. Encore merci.

Je vais finaliser tout ça pendant les vacances et après un voyage au Danemark dès mercredi matin. Je reviendrai te présenter le produit final!

Je vais mieux dormir… :wink: MERCI!