cómo implementar la carga diferida de imágenes en la vista de tabla usando swift

Quiero utilizar el concepto de carga diferida para mi vista de tabla usando swift. En mi vista de tabla, estoy mostrando varias celdas que contienen imágenes de producto y nombre de producto. Por favor, ayúdame a obtener la solución.

Vieja solución:

Dado que no muestra ningún código.

Aquí está el ejemplo para ti.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // try to reuse cell let cell:CustomCell = tableView.dequeueReusableCellWithIdentifier("DealCell") as CustomCell // get the deal image let currentImage = deals[indexPath.row].imageID let unwrappedImage = currentImage var image = self.imageCache[unwrappedImage] let imageUrl = NSURL(string: "http://staging.api.cheapeat.com.au/deals/\(unwrappedImage)/photo") // reset reused cell image to placeholder cell.dealImage.image = UIImage(named: "placeholder") // async image if image == nil { let request: NSURLRequest = NSURLRequest(URL: imageUrl!) NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in if error == nil { image = UIImage(data: data) self.imageCache[unwrappedImage] = image dispatch_async(dispatch_get_main_queue(), { cell.dealImage.image = image }) } else { } }) } else{ cell.dealImage.image = image } return cell } 

Siga ESTE tutorial para obtener más información. Espero que esto te ayudará.

Nueva solución:

Aquí hay una extensión creada por mi amigo Leo Dabus que es realmente fácil de usar:

 extension UIImageView { func downloadImageFrom(link link:String, contentMode: UIViewContentMode) { NSURLSession.sharedSession().dataTaskWithURL( NSURL(string:link)!, completionHandler: { (data, response, error) -> Void in dispatch_async(dispatch_get_main_queue()) { self.contentMode = contentMode if let data = data { self.image = UIImage(data: data) } } }).resume() } } 

Ahora, en su método cellForRowAtIndexPath , asigne la imagen a la celda de esta manera:

 cell.cellImageView.image = UIImage(named: "placeholder") //set placeholder image first. cell.cellImageView.downloadImageFrom(link: imageLinkArray[indexPath.row], contentMode: UIViewContentMode.ScaleAspectFit) //set your image from link array. 

Y como Rob sugirió comentar aquí, hay algunas bibliotecas útiles que puedes usar:

  1. https://github.com/Alamofire/AlamofireImage
  2. https://github.com/onevcat/Kingfisher
  3. https://github.com/rs/SDWebImage
  4. https://github.com/kean/DFImageManager

Como todavía no puedo hacer ningún comentario, aquí hay una versión de Swift 3 (Xcode 8 Beta 6) de la útil extensión proporcionada por Leo Dabus.

 extension UIImageView { func downloadImageFrom(link:String, contentMode: UIViewContentMode) { URLSession.shared.dataTask( with: NSURL(string:link)! as URL, completionHandler: { (data, response, error) -> Void in DispatchQueue.main.async { self.contentMode = contentMode if let data = data { self.image = UIImage(data: data) } } }).resume() } } 

Estoy usando esto dentro de una clase que puebla la celda de la tabla, funciona así en ese contexto muy bien, por si acaso los newbs se preguntaban si eso sería así:

 albumArt.image = UIImage(named: "placeholder") albumArt.downloadImageFrom(link: "http://someurl.com/image.jpg", contentMode: UIViewContentMode.scaleAspectFit) 

Tarea

Carga de imagen asíncrona en tableViewCell en swift 3 usando SDWebImage.

Detalles

xCode 8.3.1, swift 3.1

Muestra completa

Info.plist (agregar valor)

 NSAppTransportSecurity  NSAllowsArbitraryLoads   

Podfile

  platform :ios, '8.0' use_frameworks! target 'stackoverflow-28694645' do pod 'Alamofire' pod 'ObjectMapper' pod 'SDWebImage' end 

Gerente de Redes

 import Foundation import Alamofire // data loader class NetworkManager { class func request(string: String, block: @escaping ([String: Any]?)->()) { Alamofire.request(string).responseJSON { response in if let result = response.result.value as? [String: Any] { block(result) } else { block(nil) } } } } 

ItunceItem

 import Foundation import ObjectMapper class ItunceItem: Mappable { var wrapperType: String? var imageUrlString:String? required convenience init?(map: Map) { self.init() } private func unwrapedDescription(value: Any?) -> String { if let value = value { return "\(value)" } return "[no data]" } var description: String { var _result = "" _result += " imageUrlString: \(unwrapedDescription(value: imageUrlString))\n" _result += " wrapperType: \(unwrapedDescription(value: wrapperType))\n" _result += " price: " return _result } func mapping(map: Map) { wrapperType <- map["wrapperType"] imageUrlString <- map["artworkUrl100"] } } 

TableViewCell

 import UIKit class TableViewCell: UITableViewCell { @IBOutlet weak var artworkImageView: UIImageView! } 

ViewController

 import UIKit import SDWebImage class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! fileprivate var items = [ItunceItem]() fileprivate var viewControlerInited = false override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self tableView.tableFooterView = UIView() reloadData() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) viewControlerInited = true } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) disableDownloadingAllImages() } } // MARK: - Different extension ViewController { fileprivate func reloadData() { NetworkManager.request(string: "https://itunes.apple.com/search?term=navigator") { [weak self] json in if let _self = self { if let json = json, let array = json["results"] as? [[String:Any]] { var result = [ItunceItem]() for item in array { if let itunceItem = ItunceItem(JSON: item) { result.append(itunceItem) } } _self.items = result _self.tableView.reloadData() } } } } fileprivate func disableDownloadingAllImages() { SDWebImageDownloader.shared().cancelAllDownloads() } fileprivate func reloadImages() { for cell in tableView.visibleCells { if let indexPath = tableView.indexPath(for: cell) { let cell = cell as! TableViewCell if let imageUrlString = items[indexPath.row].imageUrlString, let url = URL(string: imageUrlString) { cell.artworkImageView.sd_cancelCurrentAnimationImagesLoad() cell.artworkImageView.sd_setImage(with: url) } } } } } // MARK: - UITableViewDataSource extension ViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 1 } public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as! TableViewCell return cell } } // MARK: - UITableViewDelegate extension ViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { let cell = cell as! TableViewCell if let imageUrlString = items[indexPath.row].imageUrlString, let url = URL(string: imageUrlString) { cell.artworkImageView.sd_setImage(with: url) } } func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { let cell = cell as! TableViewCell cell.artworkImageView.sd_cancelCurrentImageLoad() } } 

Main.storyboard

                                                                          

Resultado

enter image description here