Autolayout avecUITableViewCell

Bonjour à  tous !


 


J'ai un petit problème de compréhension sur l'ordre dans lequel la taille d'objets dans une cellule est calculée quand on utilise le storyboard et auto layout. Pourquoi je me pose cette question ? 


 


Mon réel prob est le suivant : je charge dynamiquement des cellules avec deux boutons à  l'intérieur dont la hauteur et la largeur dépendent de la hauteur du content view, à  l'aide de contraintes. 


Par la suite, quand j'appelle la méthode cellForRowAtIndexPath: , je set les cornerRadius de mes boutons de façon à  se qu'ils soient ronds : 


 


cell.nom.layer.cornerRadius=cell.nom.frame.size.height / 2;


cell.nom.clipsToBounds = YES;


 


Le résultat est que mes boutons sont absolument pas ronds mais plutôt ovales. Pourquoi ?


Premier élément de réponse, lorsque je charge une première fois la cellule, celle-ci calcule une hauteur des boutons qui ne correspond pas à  la finale. Si je fais un reloadData sur ma tableView, j'obtiens le résultat attendu (boutons rond).


Deuxième élément, je pense que je m'y prends mal de façon générale, je m'explique :


voulant faire apparaitre 6 cellules sur la page quelque soit la taille de l'écran, je fais (je pense assez bêtement) dans heightForRowAtIndexPath: 



CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;

NSInteger taille=screenSize.height/6;
if (info && indexPath.row==1) {
taille=(screenSize.height*5)/6;
}

return taille;

donc voila je galère vraiment sur ce problème, si vous pouviez m'expliquer un peu plus comment les frame sont calculées ça serait cool, ça m'éviterait de faire des reloadData pour rien...


 


Merci d'avance :)


 


Romain


 


Réponses

  • Hello !


    Je relance un petit peu ma question parce qu'elle me turlupine pas mal celle-là . En fait j'ai l'impression que la première fois qu'une cellule est chargée, les contraintes ne sont pas prises en compte, et qu'il faut les rechercher une deuxième fois pour obtenir le résultat voulu... c'est dommage qd même :/


    Donc du coup est-ce qu'il faudrait pas plutôt que je fasse toute les parties graphiques de mes boutons dans la méthode willDisplayCell:forRowAtIndexPath: ?


     


    Merci d'avance de vos conseils :)


    Romain


  • AliGatorAliGator Membre, Modérateur

    En fait j'ai l'impression que la première fois qu'une cellule est chargée, les contraintes ne sont pas prises en compte, et qu'il faut les rechercher une deuxième fois pour obtenir le résultat voulu... c'est dommage qd même :/

    Tu as essayé d'appeler "layoutIfNeeded" au début avant pour t'assurer qu'il fait le layout un peu en avance à  ce moment (et pas seulement + tard) et que tu as accès alors à  tes contraintes déjà  positionnées ?
  • RomheinRomhein Membre
    décembre 2014 modifié #4

    oui j'ai essayé de le déplacer un peu partout, même dans heightForRowAtIndexPath: mais ça ne change pas grand chose malheureusement. Est-ce qu'il y aurait pas un conflit entre mon storyboard et mon code : je set les contraintes dans le story et les arrondis dans le contrôler, enfin je sais plus trop :/


     


    EDIT: en souclassant la méthode layoutSubview de ma cellule, celle-ci est bien chargée avant l'appel de la méthode cellForRowAtIndexPath: donc logiquement les contraintes devraient être bien calculées...


     


    Enfaite ce que je comprends le moins, c'est que la hauteur affichée lors du premier chargement de la cellule est correcte en fait ! mais en revanche les arrondis le sont pas...


  • Pour avoir une image en rond, la largeur et la hauteur doivent avoir la même taille. Tu as vérifié, juste avant de modifier le layer de ton composant si ils ont la même taille ?




  • Pour avoir une image en rond, la largeur et la hauteur doivent avoir la même taille. Tu as vérifié, juste avant de modifier le layer de ton composant si ils ont la même taille ?




     


    oui effectivement, je viens de vérifier et ils ont la même taille, en fait c'est le frame de mes boutons (et aussi label, car j'ai le même prob pour mes labels) qui change de taille :


    Au premier chargement par exemple j'ai un frame avec width=height=92 (je calcul alors la taille de mes arrondies qui valent X), au deuxième width=height=89 (je calcul alors la taille de mes arrondies qui valent X').


    De plus, ce qui est vraiment bizarre, c'est que quand j'essaie de débugguer, et que je stop avant de faire un reloadData, mon iphone affiche une hauteur des boutons égale à  89, mais avec des arrondies = X' ...

  • Idée : comme tu bosses sur layers, essaye d'ajouter un petit



    [layer setNeedsDisplay] ;

    là  où ça te semble le plus pertinent...


  • RomheinRomhein Membre
    décembre 2014 modifié #8

    Merci colas2 de la proposition, je viens de trouver après 3 jours de recherche.


    Je vous le donne en mille, c'est évidemment une erreur toute bête -_-'


    J'avais oublié de décocher "Custom" dans row height du storyboard... du coup au premier chargement ça prenait toujours la valeur qui s'y trouvait et ça donnait des trucs bizarres. Maintenant c'est bon ça roule comme sur des roulettes. 


    Merci en tout cas de m'avoir aidé pour ce problème, c'est cool :)


     


    EDIT :


    ascenseur émotionnel, le prob n'est absolument pas réglé, j'avais le résultat obtenu parce que je pensais avoir commenté la ligne ou je reload ma tableView, et en fait non. Par contre ça me permet de constater que ce qu'il charge en premier c'est la hauteur de mes cellules dans mon storyboard, et il calcul les arrondies par rapport à  cette hauteur, ensuite les contraintes viennes et il affiche sur mon iphone la hauteur attendu, mais avec les mauvais arrondi.


     


    Donc colas2 j'avais effectivement déjà  effectué un setNeedsDisplay, je l'ai même placé à  des endroits insoupçonnés et dont j'ai honte mais des fois, ça ne passe pas ( :D ).


  • Autre idée : as-tu essayé de surcharger AUSSI la méthode initWithCoder ?


     


    Quand un object est crée via le .xib, son init se fait dans initWithCoder...


  • ahhhh nan j'ai pas essayé, et j'y ai même pas pensé, j'essaye ça de suite !


  • Je croise les doigts pour toi ;-)


  • pfffiooou, bien joué !


    donc au pied de biche ça passe. J'ai forcé la hauteur des cellules dans le initWithCoder: et à  la fin de cette méthode j'appelle layoutIfNeeded, et du coup il est enfin obligé de prendre en compte la hauteur des cellules, ouf!


     


    Un grand merci colas2, vraiment, parce que sans toi, j'étais en train de me retaper tout le design tellement je trouvais pas (d'ailleurs je me suis rendu compte que c'était peut-être mieux ahah).


  • Joanna CarterJoanna Carter Membre, Modérateur

    Petit truc. C'est pas nécessaire de surcharger les méthodes init... Par contre on pourrait utiliser -viewDidLoad ou -awakeFromNib, qui sont appelées, n'importe quelle méthode d'initialisation


  • ok dac, je vais essayer aussi pour voir, je pense qu'effectivement ça fonctionnera. J'avais juste pas pensé à  utiliser ma sous classe -_-'


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