2016-05-12 11 views
1

ich zu ladende A Ui Tableview mit einer Liste von Bildverbindung mit schnellen 2 zu erstellen:Der beste Weg Bild-URL swift 2 in UITableView

zum Beispiel: var images = ["link1","link2",...,linkN"]

ich erstellen Sie eine benutzerdefinierte Zelle des angezeigt werden Bild:

let cell = tableView.dequeueReusableCellWithIdentifier(CurrentFormTableView.CellIdentifiers.ImageCell, forIndexPath: indexPath) as! ImageCell 
      cell.urlImageView.tag = indexPath.row 
      cell.displayImage(images[index.row]) 
      cell.selectionStyle = UITableViewCellSelectionStyle.None 

      return cell 

Und hier habe ich meine benutzerdefinierte Zelle mein Bild zu laden:

import UIKit 

class ImageCell: UITableViewCell { 

    @IBOutlet weak var urlImageView: UIImageView! 
    @IBOutlet weak var loadingStatus: UIActivityIndicatorView! 

    override func awakeFromNib() { 
     super.awakeFromNib() 
    } 

    override func setSelected(selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 
    } 

    func loadImageFromUrl(url: String, view: UIImageView){ 
     if view.image == nil { 

      self.startLoading() 
      // Create Url from string 
      let url = NSURL(string: url)! 


      // Download task: 
      // - sharedSession = global NSURLCache, NSHTTPCookieStorage and NSURLCredentialStorage objects. 
      let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in 
       // if responseData is not null... 
       if let data = responseData{ 

        // execute in UI thread 
        dispatch_async(dispatch_get_main_queue(), {() -> Void in 
         self.stopLoading() 
         view.image = UIImage(data: data) 
        }) 
       } 
      } 

      // Run task 
      task.resume() 
     } 
    } 

    func displayImage(imageUrl: String){ 

     imageView?.image = nil 
     if imageUrl != nil && imageUrl != "" { 
      print(imageUrl) 

       loadImageFromUrl(imageUrl,view: urlImageView) 

     } else { 
      loadingStatus.hidden = true 
     } 
    } 

    func startLoading(){ 
     loadingStatus.hidden = false 
     loadingStatus.startAnimating() 
    } 

    func stopLoading(){ 
     loadingStatus.hidden = true 
     loadingStatus.stopAnimating() 
    } 
} 

Das Problem ist, dass sie mal die Bilder korrekt laden, und manchmal ein Bild oder mehr "das andere überschreiben", so dass ich mehrere identische Bilder habe anstatt alle meine verschiedenen Bilder zu sehen. Wie ist das möglich ? Wo ist mein Fehler?

Antwort

5

Sie implementieren nicht die Wiederverwendung der Zellen, was bedeutet, dass das imageView-Bild einer Zelle dasselbe ist wie das Bild, aus dem es wiederverwendet wurde, bis das neue Bild geladen wurde.

Um dies zu verhindern, implementieren die -prepareForReuse: method:

override func prepareForReuse() { 
    super.prepareForReuse() 
    urlImageView.image = nil 
    // cancel loading 
} 

Darüber hinaus sollten Sie keinen Netzwerk-bezogenen Code in der View-Ebene tun, sollte es im View-Controller erfolgen. Dadurch können Sie Caching-Mechanismen implementieren, wenn das Image bereits für eine bestimmte Zelle heruntergeladen wurde, sowie den Status anderer Sichten ändern.

das heißt aus Ihrer Sicht Controller:

var cachedImages = [String: UIImage]()  

func cellForRow...() { 
    let imageURL = imageURLs[indexPath.row] 
    if let image = cachedImages[imageURL] { 
     cell.urlImageView.image = cachedImages[imageURL] 
    } 
    else { 
     downloadImage(indexPath, { image in 
      if let image = image { 
       cachedImages[imageURL] = image 
       cell.urlImageView.image = image 
      } 
     }) 
    } 
} 

func downloadImage(indexPath: NSIndexPath, callback:() -> (UIImage?)) { 
    let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in 
      // if responseData is not null... 
      if let data = responseData { 
       // execute in UI thread 
       dispatch_async(dispatch_get_main_queue(), { 
        callback(UIImage(data: data)) 
       }) 
      } 
      else { 
       dispatch_async(dispatch_get_main_queue(), { 
        callback(nil) 
       }) 
      } 
     } 

     // Run task 
     task.resume() 
} 
+0

wo muss ich sie setzen? in der Zelle? – fandro

+0

@fandro ja, in der Unterklasse. –

+0

in der Tat funktioniert, danke, nur um sicher zu sein, ich verstehe nicht, wie ich Caching-Mechanismen und Netzwerk-bezogene implementieren kann? – fandro