[Résolu] Un bon tuto sur les UITableView ?

2

Réponses

  • septembre 2014 modifié #32

    Alors déjà  oui, j'ai lu les docs et c'est en outre pour ça que j'ai viré ma UIViewController de base pour mettre en place le UITableViewController. J'ai vu qu'il n'y avait pas besoin de faire un reloadData au premier affichage, pas besoin d'adhérer aux protocoles et il a déjà  plusieurs méthodes prêtent à  être implémenté (dis moi si je me trompe).


     


    Par contre, si je vire ma ligne de code ci-dessous, je n'ai plus de table qui s'affiche dans mon App :



    self.tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
  • AliGatorAliGator Membre, Modérateur
    septembre 2014 modifié #33

    Sinon, le UINavigationController, c'est pas plutôt dans une UIViewController que je dois l'ajouter ? (avec le UITableViewController et ensuite je test un seul Controller ? :) )

    Nope. T'as dû louper cette partie de la doc... pourtant :
    - dès la première page du Programming Guidetu as un schema,
    - tu as le même schema dans le paragraphe dédié aux "Container View Controllers" tels que le NavigationController,
    - en plus dans ce paragraphe tu as un lien enfin vers la documentation dédiée aux différents View Controllers et aux Navigation Controllers en particulier et comment les créer.

    Cette dernière doc est même vraiment bien spécialisée et détaillée, au point de te donner même le code (Listing 1-1) dans le paragraphe "Creating a navigation controller programmatically". Je pense qu'en lisant cette dernière (c'est sans doute elle que tu as loupée) tu y verras plus clair.
  • septembre 2014 modifié #34

    Concernant l'init, c'était déjà  fait :



    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self];

    Par contre, c'est le point 3 qui me pose problème :


     



     


     



    1. Set the navigation controller as the root view controller of your window (or otherwise present it in your interface).


  • Qu'est-ce qui te pose problème ? 


  • septembre 2014 modifié #36

    Je sais pas mais là  je deviens fou (tout mes essais foirent). Est-ce que je peux vous mettre le code sur un PasteBin ou un truc du genre ?


     


    (Je préfère éviter de tout mettre ici, y'a rien de super secret mais je préfère éviter).


  • AliGatorAliGator Membre, Modérateur
    septembre 2014 modifié #37
    Bah le code c'est celui du Listing 1-1 qu'il y a dans la doc, très exactement, au poil près. Pas besoin de PasteBin pour ça si c'est pour faire un copier/coller mot pour mot du code de la doc !

    Après, si tu n'as pas compris le concept du rootViewController et la hiérarchie des ViewControllers, il y a peut-être à  réviser les bases, car sinon tu vas vite t'emmêler les pinceaux et devenir fou à  tout mélanger.

    ---

    Après c'est ça de vouloir faire tout par code, certes ça te force à  comprendre comment ça marche sous le capot, mais quand tu n'es pas encore à  l'aise avec la vision d'ensemble d'une application iOS, utiliser un Storyboard ou des XIB qui font ça pour toi et t'évite le genre de prise de tête auxquelles tu t'es soumis, ça aurait été mieux et moins douloureux.

    Quitte une fois que tu as fait une ou deux applications avec Storyboard et/ou les XIB qui t'auraient facilité la vie et évité ce genre de galères, de faire ta 3ème application tout en code sans Storyboard ni XIB " si tu fais partie de ceux qui préfèrent écrire tout en code et écrire 150 lignes abstraites avec des magic numbers partout plutôt que d'avoir un visuel direct " avec Preview en plus du rendu dans toutes les résolutions et orientations possibles, et j'en passe " bien que j'ai personnellement du mal à  comprendre l'intérêt de vouloir absoluement se compliquer la vie ainsi " vu qu'avec tes 2 premières applis tu auras compris les bases concernant les autres choses (il y a déjà  tellement de choses à  maà®triser et apprendre à  côté), quand les autres trucs ne te poseront plus de problèmes tu aurais pu ainsi rajouter du challenge par petits bouts au lieu de t'attaquer directement à  tout à  la fois (pas la peine de se rajouter des bâtons dans les routes dès la première app)
  • septembre 2014 modifié #38

    Non je parlais de mon code car je n'arrive pas à  mettre en place celui de la doc.


     


    Et c'était l'occasion de te montrer mon tableView car tu me dis que c'est pas nécessaire, sauf que si je l'init pas, ça ne marche plus.


  • J'ai dis que j'avais un UITableViewController et c'est à  partir de son ViewDidLoad que je le configure et que j'ajoutes d'autres trucs.


     


    Serait-il pas mieux de faire un UINavigationController et à  partir de celui-ci créer un UITableViewController et le IUViewController pour les vues de détails ?


     


    (Ali, comment je configure mon UITableView dans mon UITableViewController si je ne dois pas faire de init ?)


  • AliGatorAliGator Membre, Modérateur


    Serait-il pas mieux de faire un UINavigationController et à  partir de celui-ci créer un UITableViewController et le IUViewController pour les vues de détails ?

    C'est pas juste mieux, c'est juste comme ça qu'il faut faire. C'est ce qui est expliqué dans la doc et ce qui est clairement fait dans le listing 1-1 également et ce vers quoi je te pointe depuis le début...

    (Ali, comment je configure mon UITableView dans mon UITableViewController si je ne dois pas faire de init ?)

    Exactement de la même manière, je ne vois pas pourquoi cela changerait. Tu n'as juste pas besoin de faire le init vu que self.tableView est déjà  alloué par le UITableViewController, si besoin d'associer son delegate et dataSource à  self car il s'en charge aussi (c'est ecrit en clair dès les premières lignes de la doc de UITableViewController Class Référence tout Ca, tu peux pas le louper...), ni besoin de l'ajouter en addSubview ou quoi, vu que cette tableView est déjà  directement la vue racine du VC...


    Mais si tu veux changer d'autres propriétés, sa backgroundColor ou sa rowHeight ou quoi, bah tu fais comme d'hab.


    Ou alors tu utilises Storyboard ou les XIB et tu te poses pas autant de questions ;-)
  • septembre 2014 modifié #41

    Désolé de poser au tant de question mais c'est pas si simple par l'intermédiaire du forum (c'est pour ça aussi que je voulais passer par PasteBin).


     


    Bon pour ce code :



    - (void)applicationDidFinishLaunching:(UIApplication *)application
    {
    UIViewController *myViewController = [[MyViewController alloc] init];
    navigationController = [[UINavigationController alloc]
    initWithRootViewController:myViewController];

    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    window.rootViewController = navigationController;
    [window makeKeyAndVisible];
    }

    Le UIViewController est-il vraiment obligatoire ?


     


    Sinon, admettons que je parte comme ça, je colle ce code dans mon AppDelegate.


     


    Ensuite je génère une nouvelles classe qui hérite de UITableViewControler qui lui va s'occuper de télécharger toutes les données, les traiter et les afficher.


     


    Puis une nouvelle classe qui hérite de UIViewController qui elle, s'occupera d'afficher la vue détail.


     


    Et donc, pas besoin de créer une nouvelle classe pour le UINavigationController car si dessus.


     


    C'est bien ça ?


     


    EDIT : bon c'est ce que j'essaye de faire mais du coup je vois bien un UITableView mais vide, il ne fais (apparemment) plus rien.


     


    EDIT 2 : quand tu dis "faire comme d'habitude", c'est à  dire ?


  • HerveHerve Membre
    septembre 2014 modifié #42

    Laisse moi vérifier quelque chose : est-ce bien des NSString que tu mets dans tes UITableView?


    Perso, quand j'ai fait mes pages pour charger les données en mémoire, j'ai fait deux tableaux :


    - l'un avec l'URL complet vers le fichier


    - l'un avec le nom débarrassé du chemin et de la terminaison grâce aux méthodes de NSString.


     


    Le TableView n'affiche que la second liste (plus jolie). Lorsque j'appuie sur "load", la fonction va chercher dans la première l'URL du fichier - grâce à  :



    int nbPatch = (int)[selectedRowIndex indexAtPosition:1]; 

    Alors seulement j'utilise NSCoding ou NSData.


     


    Est-ce ainsi que tu fais?


  • septembre 2014 modifié #43

    Je ne vois pas trop de quoi tu parles par contre mon UITableViewController fonctionne (fonctionné) très bien et affiche toutes les données correctement après les avoir téléchargés et traités.


     


    Là , c'est vraiment le UINavigationViewController qui me pose problème. Alors j'ai ce code dans le AppDelegate :



    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    //[self.window makeKeyAndVisible];

    MonTableViewController *principalView = [[MonTableViewController alloc] init];



    UIViewController *myViewController = [[WWViewController alloc] init];
    [[myViewController view] addSubview:[principalView view]];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];

    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];


    return YES;
    }

    Dans ce cas, je me retrouve avec un UITableView vide alors que je spécifie bien ma UITableViewController qui traite les données et les affiches.


     


    Si je ne demande que d'afficher mon UITableView controller, dans ce cas j'ai bien ma table qui est affiché avec toute les données et une couleur de fond. Par contre, bien sur, je ne peux pas naviguer dans les détails de chaque éléments.


     


    Tu pourras me donner le nom de ton App quand elle sera dispo ?


  • AliGatorAliGator Membre, Modérateur
    septembre 2014 modifié #44
    Ton myViewController intermédiaire ne sert a rien. Débarrasse toi de lui et utilise directement ton VC "principalView" à  la place.


    Normal que ta TableView soit vide, tu crées ton MonTableViewController mais en fait tu ne te sers que de sa view (pour l'ajouter en subview a l'autre) et pas du MonTableViewController que tu ne gardes nulle part et qui donc va aller à  la poubelle à  la fin. Donc forcément du coup ta tableView n'a plus de dataSource après et reste vide.
  • septembre 2014 modifié #45

    Tu veux dire comment ça :



    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];

    MonTableViewController *principalView = [[MonTableViewController alloc] init];

    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:principalView];

    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];

    return YES;
    }

    Parce que j'ai déjà  essayé plusieurs fois et j'ai le même résultat (UITableView affiché mais toujours vide).


  • AliGatorAliGator Membre, Modérateur
    Oui comme ça.
  • septembre 2014 modifié #47

    Alors que dois-je faire dans le UITableViewController pour qu'il affiche ses données ? J'ai mis des log et ils s'affichent mais que dalle, ça reste désespérément vide...


     


    Pourtant j'ai fais un reloadData (qui normalement n'est pas nécessaire au premier affichage).


     


    EDIT : si le AppDelegate est correct c'est bien le UITableViewController qui pose problème non ?


  • AliGatorAliGator Membre, Modérateur
    Là  je n'ai plus le temps désolé mais met des breakpoint et vérifie qu'il est toujours le dataSource de ta TV.

    Tu es un peu partie à  l'envers aussi tu aurais utilisé le bon modèle de projet dès le départ ou les XIB ou Storyboard tu n'aurais pas eu à  te prendre la tête comme ça, là  tu as voulu apprendre trop d'un coup à  vouloir tout refaire par code... Du coup ça fait trop de concepts à  t'expliquer d'un coup
  • septembre 2014 modifié #49

    En fait j'ai pas vraiment le choix. Bon si le AppDelegate est correct, ça me permet de me concentrer ailleurs...


     


    EDIT : pour l'instant je ne sais pas si c'est le DataSource mais par contre je récupère bien les données.


     


    EDIT 2 : ah oui, j'ai ce code :



    self.tableView.backgroundColor = color;
    self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    self.tableView.delegate = self;
    self.tableView.dataSource = self;

    Et la couleur n'est pas prise en compte donc j'imagine que le reste non plus.


  • septembre 2014 modifié #50

    Alors je vais faire dans l'ordre, ici, voici mon code de l'App Delegate, normalement il est bon :



    ...

    Ci-dessous la classe TableViewController :



    ...

    Donc, tout est bon sauf l'essentiel :) C'est à  dire que j'ai (apparemment) un UINavigationController qui s'affiche et une UITableView(Controller ?) mais elle, est totalement vide.

    Mes données sont bien traités et présentes, je sais aussi que les delegates du UITableViewController ne sont pas présent car à  null.

    La classe TableViewController hérite bien de UITableViewController.

     

    Voilà , merci pour votre aide.

  • Déjà  pour le reload de ta tableView : je te conseil de le passer sur la main thread/queue c'est Ali encore qui m'a conseillé cela



    dispatch_async(dispatch_get_main_queue(), ^{
    [self.tableView reloadData];
    });

    Ensuite si tu veux passer d'une NSArray avec doublon à  une sans doublon tu fait juste après la ligne ou tu déclare le set et tu fait



    self.arrayStuff = [test allObjects];

    Et la tu fait ton reloadData juste après !!

  • Am_MeAm_Me Membre
    septembre 2014 modifié #52

    Tu nous as pas montré le .h mais vérifie qu'il ressemble à  ça 



    @interface TableViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate>


    Aussi fait des NSLog dans cellForRowAtIndexPath pour voir s'il passe dedans mais avec ton code normalement ça devrait être bon


  • septembre 2014 modifié #53


    Tu nous as pas montré le .h mais vérifie qu'il ressemble à  ça 



    @interface TableViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate>


    Aussi fait des NSLog dans cellForRowAtIndexPath pour voir s'il passe dedans mais avec ton code normalement ça devrait être bon




     


    Alors non je n'ai pas mis ces protocoles, c'est justement l'intérêt d'utiliser une UITableViewController, idem pour le loadData, il est là  pour le test mais avant je l'avais pas mis car pas nécessaire. Dans les deux cas ça ne fonctionne pas (je note pour l'histoire du thread).


     


    Les protocoles ne sont pas lié (ou attaché je sais pas comment on dis), donc cellForRowAtIndexPath n'est pas appelé.


     


     


    EDIT : quand je dis avant au début de ce post, c'est justement avant que je passe d'un UITableView au UITableViewController. Et pour le loadData, il n'est pas nécessaire au premier affichage mais là  je traite les données et ensuite j'affiche.


  • Am_MeAm_Me Membre
    septembre 2014 modifié #54

    Autant pour moi oui une UITableViewCOntroller implemente deja datasource et delegate ...


     


    Mais passe tu dans cellForRow ? C'est ça ma question :)


  • Mon UITableView étant vide non (je viens de refaire un essai pour être sur). Par contre il y a un problème avec le NSSet, je vais faire ce que tu as écris plus haut, parce qu'il me retourne un count différent à  chaque fois.


  • Il te retourne un count différent mais si tu ne charge pas le même Json à  chaque fois cela peut être normal


  • Si si c'est exactement le même, pas de doutes à  avoir là  dessus.


  • Ca ne marche toujours pas en gros .... Bon je me rescan ton code car tout me paraissais correcte mais alors pour que CellForRow ne soit pas appelé je suis choqué surtout sur un UITableVieController ...


  • J'y suis depuis deux jours, j'ai essayé un tas de trucs, je comprends pas. Pour ton code, si je fais :



    self.arrayStuff = [test allObjects];

    J'ai un warning qui me dis : Incompatible pointer types assigning to 'NSMutableArray ...


     


    Effectivement j'ai dis que c'était un NSArray mais non vu que je l'alimente, c'est un NSMutableArray :)


    Donc cast à  prévoir.


  • AliGatorAliGator Membre, Modérateur
    Tu n'aurais pas, par hasard, laissé une "@property UITableView* tableView" dans ton .h ou ton .m de WWTableViewController ?

    Car la propriété "tableView" est déjà  déclarée dans un UITableViewController. Donc si toi tu en déclares une autre dans ta sous-classe, elle risque de masquer la propriété de la classe parente. Et du coup, autant la propriété tableView de la classe parente est bien initialisée avec une UITableView (c'est le UITableViewController qui s'en charge, c'est son but), autant la propriété tableView de ta sous-classe, elle, est nil et restera nil.

    Enlève la "@property UITableView* tableView" de ta classe perso, pour éviter de masquer celle de la parente, et toute devrait rentrer dans l'ordre. Et tu pourras même supprimer les lignes "self.tableView.dataSource = self" et "self.tableView.delegate = self" quand ça marchera, puisque UITableViewController faut aussi ça tout seul (alors que là  pour l'instant quand tu accèdes à  self.tableView dans ta sous-classe, tu accèdes à  ta propre propriété que tu as rajouté et qui masque celle de la UITableViewController, et comme ta propriété est nil rien ne se passera, et ton [self.tableView reloadData] dans le completionBlock de ton manager va donc correspondre à  [nil reloadData] donc c'est normal aussi qu'il ne rafraà®chisse pas ce que tu attends...)
  • septembre 2014 modifié #61

    Putain, oui j'avais laissé le code en attendant de le faire fonctionner mais effectivement, le problème est bien celui que tu soulèves (property UITableView), rhaaa comme j'ai les boules...


     


    Merci Ali.


     


    Le reste est bon pour toi sinon ?


Connectez-vous ou Inscrivez-vous pour répondre.