Validation et aide pour Architecture d'un premier programme...

BrindavoineBrindavoine Membre
00:24 modifié dans API UIKit #1
Bonjour à  tous,

Permier post sur ce sympatique forum ou l'on parle francais :)

Je suis en train de réaliser une application un poil complexe pour une première et j'aurais besoin de vos lumières sur l'architecture à  suivre.

Mon apli consiste à  pouvoir afficher en portrait une pile d'images à  la manière d'un "jeu de carte". On peut effeuiller les images en les faisant glisser avec le pouce sur la gauche hors de l'écran.

Le passage en mode portrait affiche la totalité des images d'un coup, alignées sur une grille.

La contrainte étant : le nombre d'images est variable (les images sont pour l'instant stockées en ressource et ont un nombre défini pour mes tests, mais je compte les charger dans un second temps depuis le web avec un fichier de configuration XML répertoriera les différentes urls des images à  afficher)


J'applique un effet 3D en appliquant une légère rotation (20deg) sur l'axe Y quand on fait glisser une image (comme si on la décollait en la retirant)

Je suis parti d'une View Based application

J'ai pour l'instant:
  • MonAppliAppdelegate
  • MonAppliViewController
  • LeafView (la vue d'effeuillage Portrait)


Je n'ai pas encore de vue Landscape...

Tout ce que j'ai réalisé est dans LeafView :

Chargement des images : je leur ai appliqué un masque de coins arrondis et stockage dans un NSMutableArray
(fonction awakeFromNib de ma Leafview)

Création de l'arbre de layers : je parcours mon array, et je crée un CALayer par image, je les ajoutent à  ma LeafView
(fonction drawrect de ma LeafView)

Comment ordonner mes layers en Z sans pour anatnt effectuer une translation en Z, (le dernier arrivé semble affiché en premier, si je fais une translation, celà  floute légerement l'image car elle change de taille vu que j'ai appliqué une profondeur au CALayer global) ?

Gestion des déplacement : en suivant le doigt via une CATransform3D sur le layer actif
(fonctions touchesBegan, touchesMoved et touchesEnded de ma LeafView)


J'ai donc tout mon code dans ma View... ce qui me semble bizarre pour du MVC. De plus je n'ai aucune idée comment passer en mode paysage. dois-je refaire une view ? Comment partager mes calques ?

Bref, besoin d'aide sur comment structurer tout ça (l'idéal serait de séparer aussi la gestion des "Touches")

Merci d'avance pour vos réponses

Réponses

  • AliGatorAliGator Membre, Modérateur
    00:24 modifié #2
    Hello rindavoine, et bienvenue sur osx-dev !  :adios!:


    J'ai pas encore pris le temps de tout décoder (j'entend de prendre le temps de me poser pour réaliser exactement la tête de ton archi rien qu' en lisant ce que tu as décrit), donc c'est pas impossible que je réponde pas pile bien ni exhaustivement, mais en gros déjà  pour confirmer :
    - ce que tu comptes faire ressemble un peu (même si les effets au final sont différents, mais bon sur le principe général) à  CoverFlow, non ? avec les images entassées et avec des "swipe gestures" (mouvement du doigt vers la gauche ou droite) tu passes à  la suivante en envoyant la courante à  gauche avec un effet 3D...
    - et pour le mode paysage, à  une sorte de springboard (home page de ton iPhone lisant les applis) mais à  l'horizontale, non ?

    Enfin c'est pour mieux situer l'idée... en gros, non ?




    Sinon, gérer les gestures dans la vue ne me semble pas abhérant. En gros de première approche :
    - La vue détecte les swipe gestures (mouvement de doigts) et si elle en détecte un vers la gauche, elle transmet au contrôlleur le message "je passe à  la carte suivante".
    - Le contrôlleur sait quelle est l'image courante (son index en tout cas) et communique avec le modèle pour lui demander telle ou telle image dont la vue aura besoin d'afficher (à  priori que la courante, peut-être la suivante si on en voit une partie dans la vue...)
    - Le modèle contient les données... donc dans un premier temps c'est lui qui lit ton plist et charge les images, et c'est lui qui a les fournir. Le contrôlleur va pouvoir lui demander le nombre total d'images, et l'image d'index i, et le modèle va retourner respectivement un entier pour le premier et une UIImage pour le second. Dans ta 2e phase où tu chargeras les images par le web, ton modèle aura les XML listant les URLs, et saura aller chercher la bonne image sur le net s'il ne l'a pas en mémoire quand on lui demande l'image n°X, et sinon la garder en mémoire pour i on lui demande plus tard (pour pas retélécharger à  chaque fois)


    Je te conseille de regarder le fonctionnement des TableViews (et lire le Table View Programming Guide) et d'en prendre exemple, à  mon avis c'est une architecture (tableview pour la vue, avec le système de dataSource) qu'il peut être bon de prendre pour modèle et dont tu peux t'inspirer.

    D'ailleurs perso j'ai eu à  réimplémenter une sorte de CoverFlow-like pour une démo pour mon taf, avec justement ce genre de situation d'affichage d'images avec semi-effet 3D, gestion des swipe gestures, avec une liste d'image proprement séparée de la vue... et c'est de ça que je me suis inspiré.



    Du coup tu as bien ton MVC avec V qui gère vue mais aussi gestures, et M qui contient les images, et C qui sert de dataSource à  V, et va se charger d'interroger M pour récupérer les UIImages au moment opportun.

    Voilà , sinon pour la gestion de l'orientation, ça se fait très bien avec les UIViewControllers dont c'est entre autre le rôle (ils reçoivent le mesage shouldRotationToViewOrientation quand l'iPhone est tourné) et pour ta vue sous forme de grille d'images, bah applique le même principe de MVC. D'ailleurs ça sera le même modèle, contenant tes mêmes images, y'a juste la vue (donc la représentation graphique de ton modèle à  l'écran) qui sera différente car représentant le même modèle mais d'une autre façon ;)
  • BrindavoineBrindavoine Membre
    00:24 modifié #3
    Merci pour cette réponse rapide et complète !

    Alors en effet tu as raison on peut résumer en une sorte de coverflow en Portrait et un SpringBoard en Landscape.

    J'ai bien saisi l'approche MVC que tu décrit, tout est en effet bien à  sa place, mais c'est dans l'éxécution que je bloque...

    Si j'ai bien compris, lors de l'initialisation, le controller charge le modèle qui s'occupe de récupérer les ressources. Une fois un tableau de pointeurs sur celles ci récupéré, il charge la vue, et appele par exemple des méthodes du style "addImage" pour construire visuellement le rendu.

    ensuite la vue capture les gestures et les notifie au contrôleur qui appele les bonnes fonctions du genre "moveImage" sur le layer courant et décale le pointeur courant une fois une image sortie de l'écran.

    Ais-je juste ? Est ce bien la vue qui fournit des méthodes d'interaction que le contrôlleur appelle, ou l'inverse ?

    sinon, pour le Modèle, j'avoue que je comprends le principe mais pas le détail. Dans ce que tu expliques, le chargement est "à  la demande", ce qui fait que par répercussion, la view n'affiche qu'une partie des Images ? (uniquement celles visibles comme 2 images avant et après le pointeur courant)

    Je vais regarder du coté des TableView, (j'aurais jamais pensé à  regarder la..., merci du tuyaud ! ).

    Ton coverflow, il fonctionnait de cette manière ? chargement progressif ?

    En tout cas merci encore


  • Philippe49Philippe49 Membre
    juillet 2009 modifié #4
    dans 1247176941:

    Création de l'arbre de layers : je parcours mon array, et je crée un CALayer par image, je les ajoutent à  ma LeafView
    (fonction drawrect de ma LeafView)

    Comment ordonner mes layers en Z sans pour anatnt effectuer une translation en Z, (le dernier arrivé semble affiché en premier, si je fais une translation, celà  floute légerement l'image car elle change de taille vu que j'ai appliqué une profondeur au CALayer global) ?


    Pourquoi parles-tu d'arborescence et de profondeur ?
    La vue principale (et son layer aussi) possède un tableau NSArray * appelé subviews (resp sublayers) où sont rangés les sous-vues. Lors d'un rafraichissement, la vue principale se dessine, puis les sous-vues sont dessinées dans l'ordre des indices du NSArray * .
    La vue d'indice 0 se trouvant représentée est recouverte (éventuellement) par l'une des suivantes.

    UIView fournit des méthodes pour éventuellement changer l'ordre de ses subviews. 
  • BrindavoineBrindavoine Membre
    00:24 modifié #5
    Ok, le calque ayant l'indice le plus grand sera donc afficher au dessus car dessiné le dernier.

    Sinon, je parle d'arborescence de layers car j'ai un CALayer qui contient un CALayer par image (branche Portrait) et la même chose pour le Landscape.

    Mais bon je vais plutôt utiliser deux views bien distinctes plutôt que de mettre les deux modes dans la même.
  • BrindavoineBrindavoine Membre
    00:24 modifié #6
    J'ai trouvé un coverflow lopensource ici (mais en openGL pur): http://www.chaosinmotion.com/flowcover.m

    J'ai bien étudié la structure, tout est bien séparé un peu comme ce que tu as décrit, AliGator.

    Je vais m'en inspirer, ca aide pas mal d'avoir un exemple concret !

    Merci a vous deux en tout cas
Connectez-vous ou Inscrivez-vous pour répondre.