Déplacer une section d'une UITableView ?

Bonjour,


 


Cela fait un moment que je ne fais de dev iOS mais je dois maintenir une app et j'ai donc une modification à  faire.


 


C'est une app de résultats sportifs, où je récupère des données par catégorie et numéro de course (entre autres) le tout géré par CoreData.  Les 6 catégories étaient donc :


E1, E2, E3, EJ, EY, EW


Ces catégories sont donc les sections de mon UITableView. Le gros avantage était que le tri par catégorie me donnait le bon ordre pour mes sections.


 


Mais cette année  il y a une nouvelle catégorie appelée "GP". Cette catégorie  se retrouve en dernier une fois le tri effectuée par NSFetchedResultsController :  E1, E2, ..... , EW, GP. 


Mais cette catégorie GP doit se trouver en premier  :  GP, E1, E2, .... 


 


Y-a-t il un moyen simple de faire en sorte que la section se  retrouve en premier dans mon UITableView ?  


 


J'ai cherché pour faire ça juste après le performFetch mais je n'ai pas trouvé .  Faut dire que ça doit faire 2 ou 3 ans que je ne fais plus de dev alors j'ai un peu de mal :-( 


 


Merci d'avance pour le coup de main !


Sergio


 


 


 


Mots clés:

Réponses

  • Une solution normale serait d'ajouter une entité dans la base CoreData pour associer chaque catégorie à  un ordre de classement. Du coup il y aurait juste une ligne de code à  modifier pour que la clé de tri ne soit plus le nom de la catégorie mais l'ordre de classement.


    Malheureusement la modification du schéma CoreData n'est pas simple si on veut que la nouvelle version de l'application lise les anciennes bases CoreData et crée cette entité supplémentaire à  la volée ; il faut jouer avec les versions de schéma.


     


    Une autre solution serait de bricoler le NSSortDescriptor utilisé lors de la création du NSFetchedResultsController. Il faudrait créer un NSSortDescriptor avec un bloc NSComparator dans lequel tu forces GP à  être au début de la liste. C'est un affreux bricolo mais pas très compliqué à  coder.


  • Merci pour les idées.


    Une entité dans la base CoreData : une bonne idée mais ça risque de me faire quelques modifs et donc du test à  faire, et donc du temps :(   (c'est un championnat du monde, 1ère manche dans 10  jours). 


    Ceci dit, je retiens !


     


    Le NSSortDescriptor : j'y ai pensé mais à  priori ce n'est pas possible car ce NSSortDescriptor est plus ou moins compilé et transmis au SQLite et on ne peut pas appeler sa propre méthode pour le selector. C'est ce que j'ai lu dans mes recherches sur le Net.


     


    Sinon entre temps, j'ai trouvé peut-être une autre solution : faire 2 NSFetchedResultsController alimentant ma UITableView,  un avec la nouvelle categorie GP , le second avec les autres catégories. 


     


    S'il y a d'autres idées, je suis preneur  :) 

  • CéroceCéroce Membre, Modérateur

    Le NSSortDescriptor : j'y ai pensé mais à  priori ce n'est pas possible car ce NSSortDescriptor est plus ou moins compilé et transmis au SQLite et on ne peut pas appeler sa propre méthode pour le selector.

    La méthode -initWithKey:ascending:comparator: prend un bloc en paramètre, qui effectue la comparaison. Il y a aussi -initWithKey:ascending:selector:.
  • Oui. J'avais jeté mon dévolu sur -initWithKey:ascending:comparator: ou +sortDescriptorWithKey:ascending:comparator: qui me paraissent simples à  mettre en oeuvre dans ce cas précis.


     


    Deux NSFetchedResultsController ça me paraà®t plus compliqué à  mettre en oeuvre. L'interface de NSFetchedResultsController est vraiment pensée pour qu'une instance soit appairée avec un UITableViewController.


  • Solution facile et moche : Tu appelles ta nouvelle catégorie "AAGP" et au moment de l'affichage, tu enlèves les "AA".


     


    Comment enlever les "AA" ?


    Si tu ne passes pas par un datasource en code (ce que j'imagine ; sinon tu peux le faire), mais par des "bindings" : tu peux créer une @property realTitleCategory sur tes entités et c'est celle-là  que tu affiches.


     


    Mon idée est basée sur des hypothèses sur comment marche le FetchMachin (que je n'ai jamais utilisé).


     


    Si c'est pas clair, n'hésite pas à  me demander des compléments.


  • Pour ce qui est du NSSortDescriptor dans un NSFetchedResultsController ce n'est à  priori pas possible.J'ai pas mal cherché autour de ces 2 classes sur stackOverflow et les intervenants parlent souvent de problèmes avec son propre NSSortDescriptor , on récupère en général une erreur "unsupported NSSortDescriptor".  J'ai essayé avec un block et c'est ce que j'ai eu.  Il y a peut-être un moyen mais je pense que ce n'est pas simple.


     


    En fait j'ai repris l'idée de jpimbert ,   j'ai rajouté une entité categOrder et lorsque j'importe les données j'ai juste à  mettre une valeur par défaut pour ce categOrder (1 par exemple) et 0 pour la categorie GP.  Autre avantage : je pourrais éventuellement modifier l'ordre d'affichage des catégories.  Ca a été finalement peu de boulot et ça fonctionne :-)


     


    En tous cas , merci pour les propositions


    Sergio

  • jpimbertjpimbert Membre
    mars 2016 modifié #8

    Ce n'est pas une application déjà  en production, avec des fichiers SQLite déjà  existants avec l'ancien format ?


    J'avais cru comprendre ça car tu disais que c'est une application en maintenance.


     


    Si c'est une application toute neuve, l'entité supplémentaire est le plus simple à  coder.


    Dans le cas contraire il aurait fallu gérer le versionning de schéma pour convertir les fichiers déjà  existants.


  • CéroceCéroce Membre, Modérateur

    Pour ce qui est du NSSortDescriptor dans un NSFetchedResultsController ce n'est à  priori pas possible.J'ai pas mal cherché autour de ces 2 classes sur stackOverflow et les intervenants parlent souvent de problèmes avec son propre NSSortDescriptor , on récupère en général une erreur "unsupported NSSortDescriptor".  J'ai essayé avec un block et c'est ce que j'ai eu.  Il y a peut-être un moyen mais je pense que ce n'est pas simple.

    Tu viens de m'apprendre un truc, je ne connaissais pas cette limitation, que tu as par ailleurs fort bien expliquée plus haut.
    La doc de NSFetchRequest.sortDescriptors ne mentionne même pas cette limitation.


  • Tu viens de m'apprendre un truc, je ne connaissais pas cette limitation, que tu as par ailleurs fort bien expliquée plus haut.

    La doc de NSFetchRequest.sortDescriptors ne mentionne même pas cette limitation.




    Je n'ai pas étudié le truc à  fond, mais est-ce parce que ça transforme les requêtes en SQL-lookalike, et que du coup le sort avec un block est intraduisible ? Ce qui serait également " expliqué " par la limitation sur les NSPredicate qui ne peuvent être avec block non plus dû lors de recherches CoreData.

  • AliGatorAliGator Membre, Modérateur
    Oui c'est pour cette raison.


  •  


    Si c'est une application toute neuve, l'entité supplémentaire est le plus simple à  coder.


    Dans le cas contraire il aurait fallu gérer le versionning de schéma pour convertir les fichiers déjà  existants.




     


    La conversion est transparente s'il s'agit d'un simple ajout de propriété.


    Mais il y a peut-être quelques lignes à  ajouter lors de la création de la stack coredata pour avoir l'option de migration automatique.

  • FKDEVFKDEV Membre
    avril 2016 modifié #13

    Pour compléter:


    Il est possible d'utiliser un NSSortDescriptor qui ne se traduit pas en SQL à  condition que tous les objets concernés soient déjà  chargés en mémoire.


    Il faut donc déjà  faire une première requête pour charger les objets en mémoire (sans "fault") puis utiliser le tri avancé.


    C'est une technique qui n'est pas documentée, donc à  déconseiller... mais ça peut dépanner.


    L'autre possibilité c'est de transférer les objets dans un store temporaire qui ne soit pas en SQLLite.


  • colas_colas_ Membre
    avril 2016 modifié #14

    À propos de migration, si certains doivent gérer des migrations plus complexes, voici un lien bien utile.


    https://www.objc.io/issues/4-core-data/core-data-migration/


     


    Je me suis basé dessus pour mettre en place les transitions un peu délicates entre versions.


     


    EDIT:


    le projet github https://github.com/objcio/issue-4-core-data-migration


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