Le problème:
J'ai une CollectionView qui charge une UIimage dans chaque cellule. Cependant, mon problème est que lorsque je charge des cellules supplémentaires avec plus d'images, elles semblent se dupliquer. Je ne peux pas vraiment voir ce qui pourrait causer cela dans mon code. Cela peut-il être dû à un problème avec des cellules réutilisables?
Quelqu'un peut-il voir pourquoi cela se produit?
NOTE: Le tableau avec les images n'a pas de duplicates
Vidéo du problème: https://www.youtube.com/watch?v=vjRsFc8DDmI
Image du problème:
Voici mes fonctions pour collectionView:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { //#warning Incomplete method implementation -- Return the number of items in the section if self.movies == nil { return 0 } return self.movies!.count } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UpcomingCollectionViewCell if self.movies != nil && self.movies!.count >= indexPath.row { // Calc size of cell cell.frame.size.width = screenWidth / 3 cell.frame.size.height = screenWidth / 3 * 1.54 let movies = self.movies![indexPath.row] if(movies.postrPath != "" || movies.postrPath != "null"){ cell.data = movies.postrPath } else{ cell.data = nil } // See if we need to load more movies let rowsToLoadFromBottom = 5; let rowsLoaded = self.movies!.count if (!self.isLoadingMovies && (indexPath.row >= (rowsLoaded - rowsToLoadFromBottom))) { let totalRows = self.movieWrapper!.totalResults! let remainingMoviesToLoad = totalRows - rowsLoaded; if (remainingMoviesToLoad > 0) { self.loadMoreMovies() } } } else { cell.data = nil } return cell } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: screenWidth/3, height: screenWidth/3*1.54) }
Ici, je charge datatables d'une class Wrapper:
func loadFirstMovies() { isLoadingMovies = true Movies.getMovies({ (movieWrapper, error) in if error != nil { // TODO: improved error handling self.isLoadingMovies = false let alert = UIAlertController(title: "Error", message: "Could not load first movies \(error?.localizedDescription)", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) } self.addMoviesFromWrapper(movieWrapper) self.activityIndicator.hidden = true self.isLoadingMovies = false self.collectionView.reloadData() }) } func loadMoreMovies(){ self.isLoadingMovies = true if self.movies != nil && self.movieWrapper != nil && self.movieWrapper!.page < self.movieWrapper!.totalPages { // there are more species out there! Movies.getMoreMovies(self.movieWrapper, completionHandler: { (moreWrapper, error) in if error != nil { // TODO: improved error handling self.isLoadingMovies = false let alert = UIAlertController(title: "Error", message: "Could not load more movies \(error?.localizedDescription)", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) } print("got more!") self.addMoviesFromWrapper(moreWrapper) self.isLoadingMovies = false self.collectionView.reloadData() }) } } func addMoviesFromWrapper(wrapper: MovieWrapper?) { self.movieWrapper = wrapper if self.movies == nil { self.movies = self.movieWrapper?.results } else if self.movieWrapper != nil && self.movieWrapper!.results != nil { self.movies = self.movies! + self.movieWrapper!.results! } }
Et enfin j'appelle: loadFirstMovies()
dans viewDidLoad()
EDIT: Le UpcomingCollectionViewCell
class UpcomingCollectionViewCell: UICollectionViewCell { @IBOutlet weak var imageView: UIImageView! var data:Ssortingng?{ didSet{ self.setupData() } } func setupData(){ self.imageView.image = nil // reset the image if let urlSsortingng = data{ let url = NSURL(ssortingng: "http://image.tmdb.org/t/p/w342/" + urlSsortingng) self.imageView.hnk_setImageFromURL(url!) } } }
Il s'agit d'un problème de configuration de vue de table / collection typique.
Chaque fois que vous recyclez une cellule à l'aide d'une méthode dequeueReusableCellWithReuseIdentifier:
comme dequeueReusableCellWithReuseIdentifier:
vous devez toujours configurer complètement toutes les vues de la cellule, y compris la définition de toutes les zones de text / images à leurs valeurs initiales. Votre code a plusieurs instructions if où, si la condition de if est fausse, vous ne configurez pas les vues dans la cellule. Vous devez disposer d'autres clauses qui suppriment l'ancien contenu des vues de la cellule au cas où du contenu subsisterait depuis la dernière utilisation de la cellule.
**MODIFIER:
Changez votre méthode cellForItemAtIndexPath
pour commencer comme ceci:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UpcomingCollectionViewCell cell.imageView.image = nil; //Remove the image from the recycled cell //The rest of your method ...
Dans la méthode setupData()
vos cellules personnalisées, essayez ce qui suit:
func setupData(){ self.imageView.image = nil // reset the image if let urlSsortingng = data{ let url = NSURL(ssortingng: "http://image.tmdb.org/t/p/w342/" + urlSsortingng) self.imageView.hnk_setImageFromURL(url!) } }