Charger plusieurs images dans un scrollView et plantage
Bonjour à tous,
J'ai un petit problème. Je voudrais charger des miniatures d'images dans un scrollView comme dans l'application Photos quand on a l'aperçu de toutes les photos.
Ca passe parfaitement sur le simulateur mais le device ne supporte pas que charge plus d'une dizaines d'images. Si j'en charge plus l'application plante simplement.
Comment faire pour afficher ces images sans que cela soit trop lourd pour l'application ?
Mes images originales sont assez grande elle font 330x465
J'ai un petit problème. Je voudrais charger des miniatures d'images dans un scrollView comme dans l'application Photos quand on a l'aperçu de toutes les photos.
Ca passe parfaitement sur le simulateur mais le device ne supporte pas que charge plus d'une dizaines d'images. Si j'en charge plus l'application plante simplement.
Comment faire pour afficher ces images sans que cela soit trop lourd pour l'application ?
Mes images originales sont assez grande elle font 330x465
NSBundle * mainBundle=[NSBundle mainBundle];<br /> <br /> if ([[reponseArray objectAtIndex:0] isEqualToString:@"COLLECTION BOX"])<br /> {<br /> for (int i = 0 ; i < [reponseArray count]; i++)<br /> {<br /> <br /> for (int col = 0 ; col <= 4; col++)<br /> {<br /> <br /> UIImage * myImage = [[[UIImage alloc] initWithContentsOfFile: [mainBundle pathForResource:@"202" ofType:@"png"]] retain ];<br /> UIImageView * imgCard = [[[UIImageView alloc] init] retain ];<br /> [imgCard setImage:myImage];<br /> [myImage release];<br /> <br /> <br /> <br /> CGRect frame = scrollView.frame;<br /> frame.origin.x = (77 + 5) * col + 5 ;<br /> frame.origin.y = (103 + 5) * i + 5;<br /> frame.size.height = 103 ;<br /> frame.size.width = 77 ;<br /> imgCard.frame = frame;<br /> [scrollView addSubview:imgCard];<br /> [imgCard release];<br /> }<br /> <br /> <br /> }<br /> }<br />
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Allian a tort. Il ne faut surtout pas utiliser +imageNamed: pour ce genre de vue. Le +imageNamed: comme l'indique la doc, met les images en cache. Ducoup que tu fasses un retain/release dessus ou pas, l'image reste en mémoire dans l'application pour se charger rapidement au prochain appel.
Donc il faudra utiliser plutôt -initWithContentsOfFile: en utilisant NSBundle pour obtenir le chemin de l'image.
Je rajouterai même que pour gagner en fluidité, il faudra effectuer ça dans un nouveau thread et ne charger que les images visible à l'écran.
Donc ton code est juste. Le seul problème c'est que tu fais un retain sur l'image...
il faut que tu saches qu'à partir du moment où tu utilise "init", il y a déjà un retain effectué sur l'objet.
Ainsi voilà comment devrait être ton code pour éviter le plantage :
Faut vraiment faire gaffe à ce genre de chose. Non seulement tu as retenu l'image et l'imageView 2 fois, mais en plus tu les a relaché qu'une seule fois. Donc soit tu met 2 release pour l'image et 2 release pour l'imageView, soit tu retires ces retain inutiles et tu laisses le release image et release imageView
imageNamed ne fait pas vraiment un retain.. enfin on peut le voir comme ça effectivement, mais il ne faut pas croire qu'il faut faire un release après un imageNamed hein! Surtout pas!
Non c'est juste que sur iPhone il faut éviter d'utiliser imageNamed: pour tout ce qui est manipulation de photos. Après si vous devez utiliser ça pour faire des controls personnalisés ça pose aucun problème.
C'est pour simuler un mouvement.
Je fais ça :
ça dépend de l'image! Et combien tu en a, vu que je vois un "4".. si ça va de 1 à 10 par exemple.. 10 images de 2Ko c'est rien du tout. Je crois que l'iPhone a 128Mo de RAM.. (je crois).
Pour le scrolling tu parlais d'un thread
J'imagine que tu parles de ce delegate. Mais a partir de la je suis un peu perdu. Comment charger progressivement les images si il y en a 200 par exemple. Dois je removeFromSuperview les autres ?
::)
Ce n'est pas un thread mais un delegate ça.
Par contre oui sert toi de ce delegate pour faire un thread.. mais si tu n'as jamais vu les thread je te conseille de continuer comme ça meme si c'est lent. l'optimisation tu la fera plus tard.
Donc les images à charger, il faut que tu charges en premier ce qui est visible.
Si tu comptes des carré de 48*48, il faut que tu t'arranges pour calculer combien d'images sont visibles à l'écran dès le lancement.. c'est des maths pas trop compliquées quoi.
Ensuite faut absolument que tu fasses un système de NSArray, comme ça tu te retrouveras mieux.
Lorsque l'utilisateur scroll, il tu reçois "scrollViewDidScroll:", dans cette méthode tu re-calcule les images visibles (leurs index en vérité grâce), et là tu récupères leur path grâce aux index + la NSArray. Il ne faudra pas oublier effectivement de retirer les images. qui ont disparu de l'écran (enfin qui ne sont plus visibles par l'utilisateur).
J'ai eu à faire le meme genre de truc.. et comme c'était des photos qui ne bougeront pas du tout de l'application (c'est à dire que l'utilisateur n'en rajoutera pas), j'ai fait un programme sur Mac qui se charge de générer une image qui contient toutes les miniatures. à partir de là je calcule l'index de l'image que l'utilisateur selectionne grâce aux méthodes de touch. Là au moins ça plantait pas vu que c'est une seule image de 320 de largeur et X hauteur.
Donc si t'es dans le meme cas que moi et que l'utilisateur n'a pas à rajouter des images, je peux te filer le générateur de miniatures.