gpt4 book ai didi

ios - UICollectionView cellForItemAtIndexPath 在滚动时一遍又一遍地调用

转载 作者:搜寻专家 更新时间:2023-11-01 07:23:59 26 4
gpt4 key购买 nike

我有一个 UICollectionView,其中每个单元格都是从 Flickr 异步填充的。

在我的场景中,我想要 21 个单元格,我的代码可以很好地生成它。但是,即使在 cellForItemAtIndexPath 方法中填充了所有 21 个单元格之后,我的代码还是一次又一次地调用 Flickr。我查看了 Apple 文档,但没有看到任何地方声明 cellForItemAtIndexPath 应该在滚动时连续调用。

我希望每个单元格只填充一次,然后一旦完成 cellForItemAtIndexPath 就不应再次调用。

这是我的代码:

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 1
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
print("test") // <--- this prints over and over again on scrolling
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("ImageCell", forIndexPath: indexPath) as! FlickrImageCellViewController
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(queue) { () -> Void in
let url = NSURL(string: self.imageURLSet[indexPath.row])
let data = NSData(contentsOfURL: url!)
let img = UIImage(data: data!)

dispatch_async(dispatch_get_main_queue(), {
cell.imageView.image = img
})


}

// This is where the cells are being populated


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){
print("record")
print(record["url_m"] as! String)
print("end record")
self.imageURLSet.append(record["url_m"] as! String)

}
}
}
}

override func viewDidAppear(animated: Bool) {

self.collectionView.reloadData()
}
}

最佳答案

这是因为 UICollectionView 重用了单元格。每次重新调整单元格的用途时,都会调用 cellForItemAtIndexPath:。显然,每次重复使用一个单元格时都进行网络调用是不理想的。

容纳单元重用和网络调用的最佳方法是实现缓存。这可以是像字典一样简单的东西,其中键是您的索引路径,值是您的 Flickr 图像。 [NSIndexPath: UIImage]

当调用 cellForRowAtIndexPath 时:

1) 使用 indexPath 作为键检查图像的缓存。

2) 如果该键有一个 UIImage,请将其设置在您的单元格中。

3) 如果该索引路径没有缓存的 UIImage,则进行网络调用。当它返回时,将结果添加到您的缓存并更新单元格。

关于您的代码的注释:

由于单元格被重用,您的网络调用可能会在您的 Collection View 单元格显示与发起调用的对象不同的对象时返回。您应该进行某种检查,以确保单元格当前显示的 indexPath 是返回图像的正确索引路径。如果不这样做,可能会导致您为给定数据显示错误的图像。

关于ios - UICollectionView cellForItemAtIndexPath 在滚动时一遍又一遍地调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37169087/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com