UITableView Rapide

2»

Réponses

  • 'jojolebg' a écrit:
    Je viens de tomber sur un cas ou l'utilisation de cellForRowAtIndexPath ne marche pas dans l'utilisation que l'on fait. En effet parfois on rentre à  l'interieur du dispatch_async avant meme de faire le return cell,(donc dès fois c'est synchrone) Et à  l'interieur du dispatch_async on appel la méthode cellForRowAtIndexPath qui va forcement renvoyé nil car le return Cell n'a pas été fait. Pour l'instant chez moi ce cas n'arrive qu'a la première cellule de la tableview, et qu'au premier chargement. Il y a surement un moyen de ruser. Mais les deux cas ne sont pas directement interchangeable.




    Je suis très étonné de ce comportement. Je ne vois même pas comment c'est possible.



    Puisque le cellForRowAtIndexPAth: est effectué sur la mainQueue en async. Ce sera donc appellé une fois le cycle actuel terminé, donc forcément on aura fait un return de la cell d'abord.



    Si tu mets un log juste avant le return et un log juste avant le cellForRowAtIndexPath, tu obtiens le log du return en second ? O_o

    Quelqu'un dans la salle qui peut m'expliquer comment c'est possible ?
  • 'jojolebg' a écrit:


    Je n'ai pas Gimp installer sur mon poste, mais je n'arrive pas à  reproduire Draken.

    J'ai essayé pas mal de reglages avec photoshop mais je n'arrive pas à  avoir des images plus legère que la version jpg.


    Je n'utilise pas PhotoShop, préférant GIMP qui est gratuit. Voici le réglage que j'ai utilisé :
  • jojolebgjojolebg Membre
    avril 2012 modifié #34
    Quand je choisie le meme reglage sur photoshop, l'image fait 1,4mo. Je vais essayer avec the Gimp.



    Edit:

    C'est genial

    On divise par 4 la taille de l'image et la qualité est quasi identique.

    Faut que je trouve un moyen de faire un traitement par lot sur tout un dossier en utilisant l'export png de Gimp maintenant.
  • jojolebgjojolebg Membre
    avril 2012 modifié #35
    Bonjour, je reviens vers vous.

    En rajoutant cette ligne (pour reduire l'image) juste avant de mettre l'image dans le NSCache (et de l'afficher), le tableview sera vraiment beaucoup plus fluide.

    En effet, on avait déjà  parallelisé l'ouverture de l'image avec GCD, mais l'affichage ne pouvait pas être parallélisé, et s'agissant d'une grosse image cela bloqué l'UI lors de l'affichage.

    Avec cette méthode l'affichage est plus rapide, donc la tableview est plus fluide.

    Je garde aussi la technique de l'image en basse résolution. Donc je combine les deux.


    <br />
    [size=3][size=3]UIImage[/size] [size=3][b]*[/b][/size][size=3]resizedImage[/size] [size=3][b]=[/b][/size] [size=3][[/size][size=3]image[/size] [size=3]resizedImageWithContentMode:[/size][size=3]UIViewContentModeScaleAspectFill[/size][/size]<br />
    [size=3][size=3]bounds:[/size][size=3]CGSizeMake[/size][size=3]([/size][size=3]cellHeight[/size][size=3],[/size] [size=3]cellHeight[/size][size=3])[/size][/size]<br />
    [size=3][size=3]interpolationQuality:[/size][size=3]kCGInterpolationHigh[/size][size=3]];[/size][/size]<br />
    


    La ligne peux être trouvé dans se projet.

    https://github.com/S...ntroller.m#L147





    Edit:

    En relisant le topic je m'apeçois, que Jegnux me conseillé de faire ça dès sa première réponse.




    [font=helvetica, arial, sans-serif]Posté [/font]09 avril 2012 - 13:18

    [font=helvetica, arial, sans-serif]Bon prou commencer, tu dis que tes images font la taille de l'ecran de l'iPhone, mais est-ce que les cellules elles mêmes font cette tailles ?



    L'idée serait de redimensionner par le code tes images pour qu'elles fassent la taille de ton imageView.
    [/font]
  • jojolebgjojolebg Membre
    mai 2012 modifié #36
    'Kubernan' a écrit:


    Tu peux aussi aplatir la hiérarchie de tes vues. C'est ce que je fais pour certaines de mes cells qui affichent pas mal d'image : plutôt que de multiplier les UIImageView, je dessine (via drawRect:) toutes mes images dans une seule vue par la méthode drawAtPoint: de UIImage.




    Re-bonjour à  tous.

    J'essaye d'applitir ma hiérachie de vue sur une UITableViewCell, donc de ne plus utiliser UILabel, mais seulement drawAtPoint ou drawAtRect de NSString(Drawing), car j'ai cru lire sur certains site qu'avoir trop de subview ralentissait l'affichage, et que c'était mieux d'avoir un drawRect qui dessine le texte.



    Chose faite et j'obtiens quelque chose qui ressemble à  ça (equivalent à  un seul label)
    <br />
    - (void)setMyString:(NSString *)myString<br />
    {<br />
       _myString = myString;<br />
       [self setNeedDisplay];<br />
    }<br />
    <br />
    - (void)drawRect:(CGRect)rect {<br />
      <br />
    #define LEFT_COLUMN_OFFSET 10<br />
    #define LEFT_COLUMN_WIDTH 130<br />
      <br />
    #define UPPER_ROW_TOP 8<br />
    <br />
    #define MAIN_FONT_SIZE 18<br />
    #define MIN_MAIN_FONT_SIZE 16<br />
    <br />
    	// Color and font for the main text items (time zone name, time)<br />
    	UIColor *mainTextColor = [UIColor blackColor];;<br />
    	UIFont *mainFont = [UIFont systemFontOfSize:MAIN_FONT_SIZE];<br />
    	  <br />
    	CGRect contentRect = self.bounds;<br />
    	CGFloat boundsX = contentRect.origin.x;<br />
    	  <br />
    	// Set the color for the main text items.<br />
    	[mainTextColor set];<br />
    	  <br />
    	CGPoint point; = CGPointMake(boundsX + LEFT_COLUMN_OFFSET, UPPER_ROW_TOP);<br />
    	[myString drawAtPoint:point forWidth:LEFT_COLUMN_WIDTH withFont:mainFont minFontSize:MIN_MAIN_FONT_SIZE actualFontSize:NULL lineBreakMode:UILineBreakModeTailTruncation baselineAdjustment:UIBaselineAdjustmentAlignBaselines];<br />
    <br />
    }<br />
    




    Inconvénients majeur:

    Ma tableView saccade énormement. La méthode setMyString et appellé à  chaque fois qu'une cellule sera affiché (la méthode est appelé dans le tableView:cellForRow). Donc drawRect est souvent appelé, et j'ai l'impression que sa ralentit la tableView.



    Quelque chose que j'ai mal fait ?
  • As-tu testé en enlevant [self setNeedDisplay] ? À mon avis l'appel à  cette méthode ne sert à  rien ici. Et si tu laisses ton label ça donne quoi ?
  • jojolebgjojolebg Membre
    mai 2012 modifié #38
    Quand j'enlève le setNeedDisplay l'affichage des cellules n'est jamais reactualisé, et c'est embettant quand on utilise des reuse cells.

    Quand j'utilise un UILabel, je n'est pas besoin de faire un setNeedDisplay, le label se reactualise directement.
  • 'jojolebg' a écrit:


    Quand j'enlève le setNeedDisplay l'affichage des cellules n'est jamais reactualisé, et c'est embettant quand on utilise des reuse cells.

    Quand j'utilise un UILabel, je n'est pas besoin de faire un setNeedDisplay, le label se reactualise directement.




    Oula ! oui ! Quelqu'un a dû parler à  ma place hier c'est pas possible.

    Concernant le UILabel, ma question était sur les performances à  comparer : avec/sans.



    Qu'est-ce qui te faire dire que c'est bien le code que tu présentes qui provoque un affichage saccadé ? As-tu passé ton code sous Time Profiler ? Tu as peut-être quelque chose dans ton tableView:CellForRowAtIndexPath qui ralenti tout ça.




    'jojolebg' a écrit:


    Re-bonjour à  tous.

    J'essaye d'applitir ma hiérachie de vue sur une UITableViewCell, donc de ne plus utiliser UILabel, mais seulement drawAtPoint ou drawAtRect de NSString(Drawing), car j'ai cru lire sur certains site qu'avoir trop de subview ralentissait l'affichage, et que c'était mieux d'avoir un drawRect qui dessine le texte.




    "Trop de subView" ne signifie pas non plus qu'il ne faut plus en avoir. J'ai par exemple une sous classe de UITableViewCell pour laquelle j'insère une custom view dans contentView: Et c'est dans cette custom view que je fais le drawRect: de tous mes éléments.
  • jojolebgjojolebg Membre
    mai 2012 modifié #40


    Concernant le UILabel, ma question était sur les performances à  comparer : avec/sans.




    Les performances sont sans comparaison, avec le UILabel tout est fluide. En effet le tableview:cellForRowAtIndexPath ne fait pas grand chose, juste charger le contenu dans la cellule (et si j'utilise drawRect à  la place de UILabel, la cellule fait un setNeedDisplay)


    "Trop de subView" ne signifie pas non plus qu'il ne faut plus en avoir. J'ai par exemple une sous classe de UITableViewCell pour laquelle j'insère une custom view dans contentView: Et c'est dans cette custom view que je fais le drawRect: de tous mes éléments.


    J'ai cru comprendre en lisant cet article, que en utilisant un drawRect sur la sous-vue, cela améliore nettement les performances.

    En effet le drawRect sur la cellule n'appelle pas le drawRect sur les sous-vues, donc les sous-vue ne sont calculer qu'une seule fois.

    C'est ce que j'ai fait pour le moment pour afficher un degrader et customiser le background de ma cellule. Le background est n'est généré qu'une seule fois (le drawrect n'est appelé qu'une seul fois), ce qui améliore les perfs considerablement.



    J'ai aussi essayé de mettre les dessins dans le drawrect la customView, mais rien n'y fait, j'ai besoin de faire un setNeedDisplay pour les mettres a jour, et des que je rajoute setNeedDisplay, la tableview saccade.



    Dans ton cas ou met tu le setNeedDisplay ?



    Merci pour ton aide.
  • 'jojolebg' a écrit:




    Dans ton cas ou met tu le setNeedDisplay ?






    setNeedsDisplay. Nulle part en fait. Pour mes besoins, j'utilise la propriété highlighted, laquelle provoque un appel à  drawRect:

    Mais si avec un UILabel tout est fluide, pourquoi faire autrement ?

    Sinon tu n'aurai pas un layoutSubviews dans ta classe ?



    Sinon je ne vois pas.
  • Pourquoi faire autrement ?




    Pour apprendre comment ça marche. J'ai commencé le developpement iPhone depuis plus d'un an, mais je ne connais toujours pas CoreGraphics, je ne connais pas la difference entre CALayer et UIView etc....

    Donc je suis en train de réapprendre certaines bases de la programmation iPhone.



    Apres, si finalement c'est mieux d'avoir des subviews (UILabel ici) pour un cas aussi simple, pourquoi pas. J'essaye juste d'optimiser certaines chose lors de mes développements.

    Mais je me demande si j'ai une cellule plus complexe, et que l'approche subview fait saccader la tableview, comment ceci réagirait avec une approche drawRect ?



    Cette approche est-elle mieux, moins bien, differente, utile, inutile, dans quel contexte l'utiliser etc....
  • 'jojolebg' a écrit:


    Pour apprendre comment ça marche. J'ai commencé le developpement iPhone depuis plus d'un an, mais je ne connais toujours pas CoreGraphics, je ne connais pas la difference entre CALayer et UIView etc....

    Donc je suis en train de réapprendre certaines bases de la programmation iPhone.



    Apres, si finalement c'est mieux d'avoir des subviews (UILabel ici) pour un cas aussi simple, pourquoi pas. J'essaye juste d'optimiser certaines chose lors de mes développements.

    Mais je me demande si j'ai une cellule plus complexe, et que l'approche subview fait saccader la tableview, comment ceci réagirait avec une approche drawRect ?



    Cette approche est-elle mieux, moins bien, differente, utile, inutile, dans quel contexte l'utiliser etc....




    Mieux, moins bien, différente, je dirai que ce n'est pas arrêté : l'aplatissement de la hiérarchie des vues peut-être une solution... jusqu'à  un certain point. Pas une règle.

    Je jongle souvent avec l'instrument Core Animation afin de vérifier où j'en suis niveau FPS. Et j'adapte mon code en conséquence.
Connectez-vous ou Inscrivez-vous pour répondre.