2016-11-20 5 views
4

Ich habe ein Problem beim Scrollen von oben nach unten dann meine tableview wiederverwendbare Zelle zeigt altes Bild, bis neuer Bild-Download abgeschlossen.Wiederverwendbare Zelle altes Bild zeigt

Es sollte meinen Standardbildplatzhalter anzeigen, bis ein neues Bild heruntergeladen wird, wenn der Download beendet ist, und dann die Bildansicht vom Bildplatzhalter zum aktuellen Downloadbild ändern. Was soll ich machen ?

Sorry für schlechtes Englisch. Wenn Sie Informationen benötigen lassen Sie mich wissen, dank

aktualisieren

Tableviewcontroller:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCell(withIdentifier: "ItemTableViewCell") as! ItemTableViewCell 
     let itemInfo = itemInfos[indexPath.row] 


     var image1 : UIImage? 
     var image2 : UIImage? 

     if let imgUrl1 = itemInfo.imageUrl { 

      image1 = ItemListViewController.imageCache.object(forKey: imgUrl1 as AnyObject) as? UIImage 


     } 

     if let imgUrl2 = itemInfo.cookerProfilePicUrl{ 
     image2 = ItemListViewController.imageCache.object(forKey: imgUrl2 as AnyObject) as? UIImage 
     } 

     cell.configureCell(iteminfo: itemInfo, img1 : image1 ,img2 : image2) 

     return cell 
    } 

Xib:

func configureCell(iteminfo:ItemInfo , img1 : UIImage? , img2 : UIImage?){ 

     if img1 != nil { 
      imageViewItemPic.image = img1 
     } 
     else{ 
      print("hi1") 
      imageViewItemPic.setImageFromURL(url: iteminfo.imageUrl!) 
     } 


     if img2 != nil { 
      imageViewCookerProfilePic.image = img2 

     } 
     else{ 
      imageViewCookerProfilePic.setImageFromURL(url: iteminfo.cookerProfilePicUrl!) 
     } 

     labelItemHeading.text = iteminfo.heading 
     labelItemDescription.text = iteminfo.description 


    } 

Update:

override func awakeFromNib() { 
     super.awakeFromNib() 
     self.imageViewItemPic.image = UIImage(named: "resto-placeholder.png") 

    } 

Update:

extension UIImageView { 

    func setImageFromURL(url: String) { 

     DispatchQueue.global().async { 

      let data = NSData.init(contentsOf: NSURL.init(string: url) as! URL) 
      DispatchQueue.main.async { 

       let image = UIImage.init(data: data as! Data) 

       ItemListViewController.imageCache.setObject(image!, forKey: url as AnyObject) 

       self.image = image 


      } 
     } 
    } 
} 
+1

Sie müssen Ihren Code von 'cellForRowAtIndexPath' – Rajat

+0

@Rajat zeigen, bitte Aktualisierungsabschnitt –

Antwort

3

Da es sich um eine wiederverwendbare Zelle ist, ist es in der Tat "wieder verwendet", um die Zelle mit dem alten Bild. Dann müssen Sie es jedes Mal, wenn die Zelle in cellForRowAtIndexPath gezeigt aktualisieren:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     cell.image=placeholder_image 
     //then download image 
} 
+0

Dank für Ihre wertvolle Lösung überprüfen –

+0

ist es am besten Praxis? –

+2

In Ihrem Fall können Sie diese Zeile in Ihre configureCell-Methode einfügen, da Sie sie von cellForRowAt aufrufen. Aber stellen Sie sicher, dass Sie mit cell.image = placeholder_image beginnen, so dass jede neue Zelle mit Platzhalter initialisiert wird, und laden Sie dann das Image herunter. Wenn der Download fehlschlägt, bleibt der Platzhalter erhalten. –

1

Sie können Ihr Standardbild in ItemTableViewCell gesetzt, wenn die Zelle initialisiert

override func awakeFromNib() { 
    super.awakeFromNib() 
    // Initialization code 
    self.image= defaultImage 
} 

bearbeiten

func configureCell(iteminfo:ItemInfo , img1 : UIImage? , img2 : UIImage?){ 

     if img1 != nil { 
      imageViewItemPic.image = img1 
     } 
     else{ 
      print("hi1") 
      imageViewItemPic.image = UIImage(named: "resto-placeholder.png") 

      imageViewItemPic.setImageFromURL(url: iteminfo.imageUrl!) 
     } 


     if img2 != nil { 
      imageViewCookerProfilePic.image = img2 

     } 
     else{ 
      imageViewItemPic.image = UIImage(named: "resto-placeholder.png") 
      imageViewCookerProfilePic.setImageFromURL(url: iteminfo.cookerProfilePicUrl!) 
     } 

     labelItemHeading.text = iteminfo.heading 
     labelItemDescription.text = iteminfo.description 


    } 
+0

nicht funktioniert das gleiche Ergebnis –

+0

Bitte überprüfen Sie meine Update-Abschnitt. Ist es richtig, dass ich das getan habe? –

+0

Ja ist es richtig, was ist diese Methode 'setImageFromURL' ist es von irgendeiner Bibliothek? – Rajat

1

Sie müssen ein Bild für jede cellForRowAtIndexPath-Funktion platzieren, dh in Ihrem Code müssen Sieschreiben 210 Bedingung für die Bildoperation und dass Sie ein Platzhalterbild platzieren müssen. Da Tabellenansichtszellen beim Scrollen nach oben und unten wieder verwendet werden, wird der alte Inhalt beibehalten, wenn Sie keinen neuen Inhalt einfügen. Aus diesem Grund werden alte/doppelte Inhalte angezeigt.

+0

erhalten Sie bitte ein Codebeispiel –

+0

Wenn itemInfo enthält den Remote-URLs, die dann benötigt, wenn –

+0

img1 = nil { imageViewItemPic.image = img1 } else { print ("hi1") imageViewItemPic.setImageFromURL vom Server herunterladen sein! (url: iteminfo.imageUrl) } –

0

genau wie ich das gleiche Problem hatte; bevor ich das gelesen habe. Ich habe verschiedene Möglichkeiten ausprobiert, wie zB init und watchfromnib. Der Weg dazu ist, sobald Sie die Daten erhalten, bevor Sie die Funktion aufrufen, um die gesamte Benutzeroberfläche zu aktualisieren.

Beachten Sie auch, im a var restData und die didSet mit (der Grund, warum es so schnell aktualisiert, wie die Daten aus dem Viewcontroller empfängt, im nicht die func aufgerufen wird. Wenn es sich um eine func vom Viewcontroller zu nennen war, würde man nur das setzen placeholder Bild zunächst am Anfang der Funktion vor dem Download des neuen Bildes und rufen Sie es von der Viewcontroller wie cell.updateUI(data: data)

Ich hoffe, ihr findet das nützlich.für mich, im richtigen Bilder bekommen, ohne auf die Zellen-Wiederverwendungs ​​das Vorschaubild zeigt :)

// Tableview Controller

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 


    let cell : RestCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RestCell 

    //configure the cell to item 
    cell.restData = items[indexPath.row] 

    return cell 
} 

// UITableViewCell

class RestCell: UITableViewCell { 

    @IBOutlet var img : UIImageView! 
    @IBOutlet var lbl : UILabel! 

    // get data and update. 
    var restData: RestsModel! { 
     didSet { 
      // default img early placeholder set. Eliminates showing old pic in cell reuse 
      self.img.image = UIImage(named: "60x60placeholder.png") 
      // Update all values func 
      updateUI() 
     } 
    } 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     // Default image placeholder 
     //self.img.image = UIImage(named: "60x60placeholder.png") 

    } 
    // required init. 
    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder)! 

     // Color of selected. 
     let myCustomSelectionColorView = UIView() 
     myCustomSelectionColorView.backgroundColor = UIColor(red: 234.0/255.0, green: 46.0/255.0, blue: 73.0/255.0, alpha: 0.1) //UIColor(netHex:0xFFFF434) 
     selectedBackgroundView = myCustomSelectionColorView 



    } 


    // updateUI func. 
    fileprivate func updateUI() { 

     // download the image 
     if (self.restData.image != nil && self.restData.image != "") { 
      ImageLoader.sharedLoader.imageForUrl(urlString:self.restData.image, completionHandler:{(image: UIImage?, url: String) in 
       self.img.contentMode = UIViewContentMode.scaleAspectFit 
       self.img.image = image 
      }) 
     } else { 
      self.img.image = UIImage(named: "60x60placeholder.png") 
     } 


     self.lbl.text = restData.name as String 



    } 

} 
0

Ganz einfach nicht viel Code schreiben Nur zwei Zeilen lösen Ihr Problem

cell.thumbnailimage.image = nil 
    cell.thumbnailimage.setImageWith(imageurl!) 
0

Legen Sie einen Standardwert für die ImageViews als "Null" i fest n Ihre XIB-Datei. Dadurch wird sichergestellt, dass kein Bild in Ihrer Zelle vorhanden ist, bevor Sie ein neues laden.

func configureCell(iteminfo:ItemInfo , img1 : UIImage? , img2 : UIImage?){ 

    //Set the imageViews to nil to make sure no other picture are set 
    imageViewItemPic.image = nil 
    imageViewCookerProfilePic.image = nil 

    //Check if img1 is not nil 
    if img1 != nil { 
     imageViewItemPic.image = img1 
    } else{ 
     print("hi1") 
     imageViewItemPic.setImageFromURL(url: iteminfo.imageUrl!) 
    } 

    //Check if img2 is not nil 
    if img2 != nil { 
     imageViewCookerProfilePic.image = img2 
    } else{ 
     imageViewCookerProfilePic.setImageFromURL(url: iteminfo.cookerProfilePicUrl!) 
    } 

    labelItemHeading.text = iteminfo.heading 
    labelItemDescription.text = iteminfo.description 


}