Je veux utiliser le concept de chargement paresseux pour ma vue de table à l'aide de Swift. Dans ma vue tableau, je montre plusieurs cellules qui contiennent des images de produit et le nom du produit. S'il vous plaît, aidez-moi à trouver la solution.
Ancienne solution:
Puisque vous n'affichez aucun code.
Voici l'exemple pour vous.
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
}
Suivez CE tutoriel pour plus d'informations. J'espère que cela vous aidera.
Nouvelle solution:
Voici une extension créée par mon ami Leo Dabus qui est vraiment simple à utiliser:
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()
}
}
Maintenant, dans votre méthode cellForRowAtIndexPath
, affectez l'image à la cellule de cette façon:
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.
Et comme Rob suggéré dans le commentaire, voici quelques bibliothèques utiles que vous pouvez utiliser:
Comme je ne peux pas encore commenter, voici une version Swift (Xcode 8 Beta 6) de l'extension utile fournie par 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()
}
}
J'utilise ceci dans une classe qui remplit la cellule du tableau, cela fonctionne très bien comme ça dans ce contexte, juste au cas où des newbs se demanderaient si cela le ferait:
albumArt.image = UIImage(named: "placeholder")
albumArt.downloadImageFrom(link: "http://someurl.com/image.jpg", contentMode: UIViewContentMode.scaleAspectFit)
Info.plist (ajouter de la valeur)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Podfile
target 'stackoverflow-28694645' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for stackoverflow-28694645
pod 'Alamofire'
pod 'AlamofireImage'
end
Code
import UIKit
import Alamofire
import AlamofireImage
class ViewController: UIViewController {
private weak var tableView: UITableView?
private var items = [ItunceItem]()
override func viewDidLoad() {
super.viewDidLoad()
let tableView = UITableView()
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
tableView.tableFooterView = UIView()
tableView.register(TableViewCell.self, forCellReuseIdentifier: "TableViewCell")
tableView.rowHeight = 100
tableView.separatorColor = .clear
self.tableView = tableView
loadData()
}
private func loadData() {
let urlString = "https://iTunes.Apple.com/search?term=navigator"
Alamofire.request(urlString).response { [weak self] response in
guard let self = self, let data = response.data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
self.items = try decoder.decode(ItunceItems.self, from: data).results
DispatchQueue.main.async { [weak self] in
guard let tableView = self?.tableView else { return }
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
}
} catch let error { print("\(error.localizedDescription)") }
}
}
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int { return 1 }
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
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? TableViewCell,
let imageUrlString = items[indexPath.row].artworkUrl100,
let url = URL(string: imageUrlString) else { return }
cell.photoImageView?.af_setImage(withURL: url)
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? TableViewCell else { return }
cell.photoImageView?.af_cancelImageRequest()
}
}
struct ItunceItems: Codable { let results: [ItunceItem] }
struct ItunceItem: Codable { var artworkUrl100: String? }
class TableViewCell: UITableViewCell {
private(set) weak var photoImageView: UIImageView?
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
selectionStyle = .none
let imageView = UIImageView()
addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 6).isActive = true
imageView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor).isActive = true
imageView.leftAnchor.constraint(equalTo: safeAreaLayoutGuide.leftAnchor).isActive = true
imageView.rightAnchor.constraint(equalTo: safeAreaLayoutGuide.rightAnchor).isActive = true
imageView.contentMode = .scaleAspectFit
photoImageView = imageView
}
required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
override func prepareForReuse() {
super.prepareForReuse()
photoImageView?.image = nil
}
}