Problème de conception : ViewController, AppDelegate, Target-Arction:"Events?"

stevesteve Membre
Bonsoir,

Je parcours ce forum depuis un petit moment maintenant sans jamais m'être inscrit. En même temps je n'avais jamais réellement eu le temps de me lancer dans le dev iOS et donc d'avoir besoin de l'aide de votre communauté.
Récemment je me suis décidé, et là , à  peine commencé que déjà  les premières questions de conception se posent.
Je suis un développeur ActionScript3, j'estime bien me débrouiller en POO et comprendre les patterns principaux.
Voici mon problème :
Dans mon fichier nib principal, MainWindow.xib, j'ajoute 9 ViewController, que je lie à  9 sous-classes de ViewController que j'ai créé.
Un de ces ViewController, appelons le HomeViewController, affiche 9 boutons qui me permettent de me rendre sur les 8 autres vues.
J'ai donc relié le "touch up inside" de ces boutons à  une IBAction dans ma classe HomeViewController. Les IBActions sont sur format showViewController1, showViewController2, etc.

Et c'est l'endroit où je coince, étant donné que mes ViewControllers sont instanciés dans mon AppDelegate, je ne vois pas comment communiquer proprement avec mon AppDelegate pour lui dire de changer la vue active.
J'ai trouvé un tuto qui m'a, de mes yeux de développeur actionscript, semblé très moche : la personne ajoutait une référence au AppDelegate dans sa classe HomeViewController, niveau dépendance on a vu mieux...

Traditionnellement en actionscript j'aurais un custom Event, que j'aurais dispatché depuis mon HomeViewController et le AppDelegate aurait été à  "l'écoute" de cet event. Mais je ne vois pas comment reproduire ce type de fonctionnement en Objective-C.
Je me dis aussi que mon approche est peut-être trop réductrice et occulte en grande partie la puissance de concepts comme Target-Action ou la délégation.
Ou peut-être que je devrais une sous-classe de ViewController, dans un modèle qui approche TabbarController ou NavigationController, car là  concrètement c'est la même problématique, mais je ne sais pas (et en même temps c'est un peu ma faute, je n'ai pas cherché à  fond dans la doc) quelle classe mère utiliser.

C'est pourquoi je sollicite votre avis sur la question, une idée sur la manière d'aborder le problème.
Merci d'avance  :)

Réponses

  • jpimbertjpimbert Membre
    23:03 modifié #2
    L'équivalent je pense (je ne suis pas développeur ActionScript) des custom events est le pattern Notification.
    Le délégué d'application peut s'abonner aux notifications qui l'intéressent, et les actions de bouton n'auront plus qu'à  émettre ces notifications.
    Mais c'est vrai aussi que de donner ces responsabilités au délégué d'application n'est pas très orthodoxe. Il serait plus "Cocoa Touch" de créer un contrôleur en s'inspirant du UITabBarController.
  • CéroceCéroce Membre, Modérateur
    mars 2011 modifié #3
    dans 1299027333:

    Et c'est l'endroit où je coince, étant donné que mes ViewControllers sont instanciés dans mon AppDelegate, je ne vois pas comment communiquer proprement avec mon AppDelegate pour lui dire de changer la vue active.

    Typiquement dans une appli iPhone, on va utiliser une UITableView pour présenter les neuf boutons qui seront de fait des UITableViewCells. L'écran de départ est donc géré par un UITableViewController, qui est le délégué de la tableview.

    Utiliser un Navigation Controller est obligatoire pour permettre de revenir à  l'écran de départ. La fenêtre contiendra donc une Navigation Bar qui contiendra la Table View.

    Dans la méthode déléguée [tt] -[tableView:didSelectRowAtIndexPath:][/tt], le tableViewController instancie le dérivé de UIViewController et affiche sa vue par un [tt][self.navigationController pushViewController:controller animated:YES][/tt].
    On n'oublie pas le [tt][controller release][/tt], car le navigation controller retient le controlleur. Quand on reviendra à  l'écran précédent, le contrôleur recevra un message [tt]-[release][/tt] et sa mémoire sera libérée. Sur iOS, pour économiser la mémoire, on n'instancie pas tous les contrôleurs au début, mais chaque fois quand on les affiche.

    Je te laisse regarder Table View Programming Guide qui explique ces choses avec force détails. Mes explications vont peut-être te paraà®tre denses, mais quand tu seras dedans, elles auront du sens.

    dans 1299027333:

    J'ai trouvé un tuto qui m'a, de mes yeux de développeur actionscript, semblé très moche : la personne ajoutait une référence au AppDelegate dans sa classe HomeViewController, niveau dépendance on a vu mieux...

    Oui, beaucoup de gens qui pondent des tutos on dû apprendre à  programmer en lisant les paquets de céréales. Il faut évidemment passer les objets de la couche 'modèle' que le view controller permet d'éditer, et seulement eux.

    dans 1299027333:

    Traditionnellement en actionscript j'aurais un custom Event, que j'aurais dispatché depuis mon HomeViewController et le AppDelegate aurait été à  "l'écoute" de cet event. Mais je ne vois pas comment reproduire ce type de fonctionnement en Objective-C.
    Je me dis aussi que mon approche est peut-être trop réductrice et occulte en grande partie la puissance de concepts comme Target-Action ou la délégation.

    Ce fonctionnement serait techniquement possible, en utilisant le NSNotificationCenter, mais il n'est pas approprié. En effet, l'AppDelegate se retrouverait alors à  devoir retransmettre la commande au contrôleur concerné.
    Utiliser les actions est plus élégant, car la cible reçoit directement l'ordre.

    (Par ailleurs si la target=nil, il existe un mécanisme complexe pour décider quel objet recevra l'action. C'est utilisé sous Mac OS notamment pour les commandes de copier-coller qui s'appliquent à  la sélection courante).
  • stevesteve Membre
    23:03 modifié #4
    Bonjour et enchanté de faire votre connaissance Céroce et jpimbert !

    Merci pour vos réponses.

    Effectivement Céroce, expliqué comme ça je vois très bien le principe et regrette de ne pas y avoir pensé avant. C'est plus que logique !
    Je me plonge dans le TableView programming guide dès que possible!

    Effectivement j'ai l'impression qu'il y a beaucoup de gens qui ont appris à  programmer dans des paquets de céréales, quel que soit le langage... Beaucoup de tutos avec de mauvaises bases sont dispo sur internet. C'est pour ça que je préférais avoir votre avis sur la question, histoire de partir dans la bonne direction.

    Une dernière question cependant, peut-être trouverais la réponse dans le programming guide, mais c'est juste pour avoir une idée sur l'approche : comment détourner le comportement initial de UITableView pour pouvoir afficher mes boutons non pas sous forme de liste, mais sous forme de grille. Je fais ça en créant des customs cells qui contiennent plusieurs de mes boutons ?

    Désolé d'abuser encore un peu !!

    Bonne journée
  • CéroceCéroce Membre, Modérateur
    23:03 modifié #5
    dans 1299061258:

    Effectivement j'ai l'impression qu'il y a beaucoup de gens qui ont appris à  programmer dans des paquets de céréales, quel que soit le langage... Beaucoup de tutos avec de mauvaises bases sont dispo sur internet.

    Alors que moi, j'ai appris grâce à  un baril de lessive Bonux.  :P

    dans 1299061258:

    Une dernière question cependant, peut-être trouverais la réponse dans le programming guide, mais c'est juste pour avoir une idée sur l'approche : comment détourner le comportement initial de UITableView pour pouvoir afficher mes boutons non pas sous forme de liste, mais sous forme de grille. Je fais ça en créant des customs cells qui contiennent plusieurs de mes boutons ?


    Disons, qu'utiliser une UITableView est la manière classique de faire. Ces tables dont très personnalisables et sont très souvent utilisées, ne serait-ce qu'à  cause de l'étroitesse de l'écran de l'iPhone.
    Mais si tu tiens vraiment à  avoir un grille, tu peux tout à  fait utiliser un UIViewController classique et une vue qui contient des boutons (à  réaliser avec Interface Builder, c'est quand même beaucoup plus simple).

    Le code n'est pas très différent:
    <br />- (IBAction) profileButton:(UIButton *)sender<br />{<br />	DetailsViewController *controller = [[DetailsViewController alloc] initWithNibNamed:@&quot;DetailsViewController&quot; bundle:nil];<br />	[self.navigationController pushViewController:controller animated:YES];<br />	[controller release];	<br />}
    
  • stevesteve Membre
    23:03 modifié #6
    Merci encore pour cette réponse.
    Je vais prendre le temps d'implémenter tout ça et je reviendrais vers vous si jamais j'ai d'autres questions.
    Merci beaucoup pour votre aide.

    Bonne journée
Connectez-vous ou Inscrivez-vous pour répondre.