从Swift中的Flickr异步加载UICollectionView的图像

时间:2016-05-11 16:08:56

标签: ios swift

我有一个UICollectionView,我在其中创建了一个继承UICollectionViewCell的类。新类包括图像插座变量。

到目前为止,我编写的代码在所有图像完全下载后显示单元格,我想异步加载这些图像,以便在每个单独的图像从Flickr下载时填充每个单元格。

我如何获得盛大的中央调度以便为我处理这个问题?

这是我的代码:

import UIKit
import MapKit
import CoreData

class ImagesCollectionViewController : UIViewController, UICollectionViewDataSource, UICollectionViewDelegate{

    @IBOutlet weak var mapView: MKMapView!

    @IBOutlet weak var collectionView: UICollectionView!
    var mapLat : Double!
    var mapLong : Double!
    let flickrApi = Flickr()
    var imageURLSet = [String]()

    override func viewDidLoad() {

        // set the location and zoom of the minimap
        let clLocation = CLLocationCoordinate2D(latitude: mapLat, longitude: mapLong)
        let span = MKCoordinateSpan(latitudeDelta: 2, longitudeDelta: 2)

        mapView.setRegion(MKCoordinateRegion(center: clLocation, span: span), animated: false)
        mapView.scrollEnabled = false

        getImages()
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imageURLSet.count
    }

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return imageURLSet.count
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("ImageCell", forIndexPath: indexPath) as! FlickrImageCellViewController

        // This is where the cells are being populated
        let url = NSURL(string: imageURLSet[indexPath.row])
        let data = NSData(contentsOfURL: url!)
        let img = UIImage(data: data!)
        cell.imageView.image = img

        return cell
    }

    //Get images from the flickr API and store in array

    func getImages(){

        let parameters : [String : AnyObject] = ["method": Flickr.Consts.GEO_METHOD, "format" : Flickr.Consts.FORMAT, "api_key": Flickr.Consts.API_KEY, "lat" : mapLat, "long" : mapLong, "nojsoncallback" : "1", "per_page" : "21", "extras" : "url_m"]

        flickrApi.performGetRequest(parameters) { (data, error) in


            for record in data as! [AnyObject]{
                if(record["url_m"] != nil){

                    self.imageURLSet.append(record["url_m"] as! String)

                }
            }
        }
    }

    override func viewDidAppear(animated: Bool) {

        self.collectionView.reloadData()
    }
}

2 个答案:

答案 0 :(得分:2)

@truongky:你的答案是对的。但是,如果图像未在本地存储时可重复使用的单元格,则会在重复使用的单元格上显示旧图像,直到下载新图像为止。

因此,在cellForRowAtIndexPath中,在新图像下载开始之前,图像应设置为nil。

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("ImageCell", forIndexPath: indexPath) as! FlickrImageCellViewController

    // set image to nil on reused cell
    cell.imageView.image = nil

    // This is where the cells are being populated
    let url = NSURL(string: imageURLSet[indexPath.row])
    let data = NSData(contentsOfURL: url!)
    let img = UIImage(data: data!)
    cell.imageView.image = img

    return cell
}

答案 1 :(得分:1)

你可以尝试SDWebImage,它可以帮到你很多。

或者您想手动下载,试试这个

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    dispatch_async(queue) { () -> Void in

    let data = NSData(contentsOfURL: NSURL(string: url)!)
    let img = UIImage(data: data!)!
    dispatch_async(dispatch_get_main_queue(), {
        // update your UI
    })
}

希望这可以提供帮助。