Passer des données d'un ViewController vers un UIView

Bonsoir à tous,

Est-il possible de passer des données entre un UIViewController et un UIView dans ce cas ?

Capture d’écran 2020-04-02 à 18.18.55|649x500

Salut!

Tout d’abord, il est déconseillé d’avoir plusieurs classes dans un même fichier. Ça peut être embêtant pour s’y retrouver plus tard!

Deuxièmement, tout dépend de ce que tu sous-entend par « données ». J’ai du mal a voir ton but avec ton screenshot. :confused:

Normalement, si la data est lié a l’UI, tu vas la stocker dans le view controller ou une subview (même si je ne vois pas quel type de Data ca pourrais être…). Si c’est lié à la logique de l’application, ca va dans le model.

Le plus simple serait de dire exactement ce que tu cherches à faire! Des personnes comme @Draken ou @ThonyF pourront t’expliquer ( Beaucoup mieux que moi! ) la démarche à suivre :smiley:

Nicolas.

Salut Nicolas,

En fait j’essaie de faire passer les données de mes textFields comme ceci : (Screenshot)
Le problème c’est que si j’enlève la class ViewController (sur le screenshot précédent), mon application ne fonctionne plus…

Salut!

Je peux te donner la solution que j’avais utiliser a l’époque si tu veux, mais je ne pense pas que ca sois la meilleure …
On m’avais expliqué que si je me retrouvais dans cette situation ( ou la tienne ) c’est que mon architecture n’était pas bonne !

Sinon voilà le bout de code que j’ai dans mes notes :

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segue_win1" {
        let bravoViewController = segue.destination as! BravoViewController
        bravoViewController.totalQuestionsPose = nombreQuestionsRestantes.text!
    }
}

var totalQuestionPose: String? —> var du controller qui reçois
var nombreQuestionsRestantes = String() → var du controller qui envoie

Mais attention ! A coté de mes notes il y avais aussi un gros triangle rouge :small_red_triangle:!

Bonne journée à toi !

@Nicow effectivement c’est une des solutions pour faire passer des informations d’un écran à un autre.

Mais comme tu le précises, l’architecture du projet joue un rôle sur la facilité de la faire.

Si je me souviens bien, on a dû te dire d’utiliser le design patterns MVC (Model View Controller).

Merci de confirmer !

Oui, le MVC! (qui deviens peu à peu le MVVC non ?)

Dans tous les cas, d’après mes maigres connaissances, si on as plus de 200 lignes de codes dans notre ViewController, c’est qu’il y a une erreur quelque part :confused: !

Tu confirmes aussi ?

Salut les gars,

Bon j’ai réussi à faire passer mes données d’un controlleur à l’autre mais petit problème, je n’arrive pas à y accéder depuis ma class UIView (ou j’ai tout le code de mon application)

Quelqu’un aurait une idée ?

Merci :pray:

Oui, MVC !!!

Normalement, il ne doit y avoir AUCUNE INFORMATION DANS LA VUE !!

Je parle du MVC dans ce sujet :

Salut @Draken,

C’est ce que j’ai essayé de faire mais si je place mon code dans le ViewController, plus rien ne fonctionne…

Le code et les données doivent se trouver dans le ViewControler. Ou pour être plus précis, les données placés dans le ViewControler sont le M (Modèle du MVC).

Là, toutes tes données sont dans la vue !

Tu saurais comment je peux faire pour placer toutes les données qui sont dans le vue vers le ViewController sans avoir des messages d’erreurs de partout ?

Voici un petit exemple d’architecture MVC.

C’est une application simpliste comptant le nombre de touches sur l’écran, en utilisant UIKit et touchesBegan.

Le Modèle ne contient qu’une seule variable : nbTouchs

La View contient juste un seul Label centré au milieu de l’écran (très sympa d’ailleurs les nouvelles contraintes pour aligner un contrôle par rapport au centre de l’écran. C’était bien plus compliqué avec les versions plus anciennes d’XCode).

Un outlet permet au viewControler de modifier le contenu de ce Label.

Par défaut, un viewControler reçoit tous les événements tactiles survenant sur sa vue principale. En gérant ces événements dans le viewControler, pas besoin de mettre du code dans la vue.

//
//  ViewController.swift
//  UIKit_touchesBegan
//

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var ui_monLabel: UILabel!
    
    var nbTouchs = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.isMultipleTouchEnabled = true
        actualiserInterface()
    }
    
    // Actualisation Interface
    // Centralisation de toutes les mises à jour
    // de l'écran dans une seule fonction
    // N'existe pas avec SwiftUI, qui s'en charge automatiquement
    func actualiserInterface() {
        ui_monLabel.text = String(nbTouchs)
    }
    
    //
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for _ in touches {
            nbTouchs += 1
        }
        actualiserInterface()
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for _ in touches {
            nbTouchs -= 1
        }
        actualiserInterface()
    }
        
}

Un seul viewControler, quelques lignes de code, une view simple avec seulement un label … et ça fonctionne …

Enfin je présume, n’ayant testé qu’avec le simulateur, qui ne gère qu’un seul Touch à la fois. Cela doit fonctionner normalement en multi-touch sur un Device.

Au fait, monsieur Apple, si tu passes par ici un jour, c’est stupide de se contenter d’un simulateur en mono-touch, sur des MacBookPro ou des Mac de bureau équipé d’un trackpad multi-touch !!


C’est simpliste (pas de mémorisation des positions de touch, pas de de petits curseurs apparaissent sous les doigts des utilisateurs) mais le code est court et fonctionnel ! C’est une base de départ …

J’ai suivi ton exemple, j’ai eu pas mal d’erreur que j’ai réussit à corriger, mais il m’en reste 4 et elles m’empêchent de tester mon app dans le simulateur :

Esce que tu les as déjà rencontées ?

La nature même des erreurs montre que tu ne comprends pas les principes de base. Tu fais comme moi, à mes débuts. Se lancer tout de suite dans la réalisation d’un projet sans prendre le temps d’acquérir les fondamentaux. Je l’ai pas mal regretté …

Tu devrais faire une pause dans ton projet, et reprendre les vidéos de maxime quelques semaines, le temps d’améliorer ton bagage technique.

Un exemple : ton utilisation des variables runCount, runCount2, runCount3 … jusqu’à runCount6. Très mauvaise approche, alors qu’on peut créer un tableau pour gérer toutes ces informations.

1 « J'aime »

C’est ce que je me suis dit aussi, mais mon appli est terminée (tout est fonctionnel) je voulais juste rajouter cette fonction qui me permet d’attribuer des noms aux joueurs sauf que pour ça j’ai besoin de passer des données d’un controller à l’autre et de refaire mon app sur le modèle MVC…
Donc je me suis dit que j’allais finir mon application et ensuite me remette à fond dans les cours pour être au top

Salut @Draken

J’ai essayé de reprendre ton code pour refaire mon app, aurait-tu une idée de comment rajouter un createViewForTouch sans forcement avoir de custom View ?

Merci :pray:

Oui … mais comme je n’ai dormi que 4 heure cette nuit, et que je viens juste de rentrer ma réponse détaillée avec un code d’exemple testé, vas attendre un peu !

Un indice quand même : tu n’as pas de Vue customisée, mais la vue principale du viewControler est accessible, comme dans cette ligne de code extraite de mon exemple :

// Activation du multi-touche sur la vue principale
self.view.isMultipleTouchEnabled = true
    import UIKit

    class ViewController: UIViewController {

        @IBOutlet weak var ui_monLabel: UILabel!
        
        var nbTouchs = 0
        var touchViews = [UITouch:UIImageView]()

        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.isUserInteractionEnabled = true
            actualiserInterface()
        }
        
        // Actualisation Interface
        // Centralisation de toutes les mises à jour
        // de l'écran dans une seule fonction
        // N'existe pas avec SwiftUI, qui s'en charge automatiquement
        func actualiserInterface() {
            ui_monLabel.text = String(nbTouchs)
        }
        
        //
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            for touch in touches {
                nbTouchs += 1
                createViewForTouch(touch: touch)
            }
            actualiserInterface()
        }
        
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            for touch in touches {
                nbTouchs -= 1
                removeViewForTouch(touch: touch)
            }
            actualiserInterface()
        }
        
        //
        func createViewForTouch( touch : UITouch ) {
            // Création UIImageView
            let imageView = UIImageView()
            imageView.image = UIImage(systemName: "bolt.circle.fill")
            imageView.frame.size = CGSize(width: 100, height: 100)
            // On place l'imageView à la position du Touch
            imageView.center = touch.location(in: self.view)
            // On pose l'imageView sur la surface de travail
            self.view.addSubview(imageView)
            // Sauvegarde Touch dans le dictionnaire
            touchViews[touch] = imageView
        }
            
        func removeViewForTouch (touch : UITouch ) {
            // Recherche de la vue correspondante au Touch
            if let view = touchViews[touch] {
                // Destruction de la vue
                view.removeFromSuperview()
                // On efface la référence de l'évenement Touch
                // dans le dictionnaire
                touchViews.removeValue(forKey: touch)
            }
        }
        
    }
1 « J'aime »

Un grand merci à toi @Draken,

Par contre depuis l’ajout de la fonction createViewForTouch le multi touch ne fonctionne plus.
J’ai essayé de rajouter :
imageView.isMultipleTouchEnabled = true
Mais rien n’y fait :man_shrugging:

Cela fonctionnait avec ma première version ?

Cci dis, qu’est-ce que tu appelle multi-touch exactement ? Normalement c’est le fait de toucher plusieurs endroits d’une surface tactile en même temps.

Tu ne confond pas le déplacement du coin de contact quand un doigt se déplace ? Si c’est ça, c’est normal. je n’ai pas implémenté cette fonction !