Swift图像放置在错误的单元格中,并在UICollectionview中不断更改
我已经搜索过了,但没有找到问题的答案,我正在从internet下载图像并将其放入“收藏”视图中,但当我滚动位置时,即使没有滚动,位置也会发生变化。我的代码如下:Swift图像放置在错误的单元格中,并在UICollectionview中不断更改,swift,swift3,uiimageview,uicollectionview,Swift,Swift3,Uiimageview,Uicollectionview,我已经搜索过了,但没有找到问题的答案,我正在从internet下载图像并将其放入“收藏”视图中,但当我滚动位置时,即使没有滚动,位置也会发生变化。我的代码如下: override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeue
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
var Label = cell.viewWithTag(2) as! UILabel
Label.text = namesArray[indexPath.row]
var image = cell.viewWithTag(1) as! UIImageView
let URLString = imgLink[indexPath.row]
let imgUrl = URL(string: URLString)
image.downloadedFrom(url: imgUrl!, contentMode: UIViewContentMode.scaleAspectFit)
UIimg.insert(image.image!, at: indexPath.row)
return cell
}
public extension UIImageView {
func downloadedFrom(url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit) {
contentMode = mode
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard
let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
let data = data, error == nil,
let image = UIImage(data: data)
else { return }
DispatchQueue.main.async() { () -> Void in
self.image = image
}
}.resume()
}
func downloadedFrom(link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
guard let url = URL(string: link) else { return }
downloadedFrom(url: url, contentMode: mode)
}
}
更新:
此函数是一个异步函数,需要一些时间才能完成
image.downloadedFrom(url: imgUrl!, contentMode: UIViewContentMode.scaleAspectFit)
所以这条线
UIimg.insert(image.image!, at: indexPath.row)
将在上述函数调用完成图像下载之前运行。这将导致您的问题
downloadedFrom函数应该使用完成处理程序在图像下载后运行一些代码,以使其正常工作
我通常使用下面的函数来获取图像
func getImage(urlString:String, completionHandler:(success:Bool, data:NSData?, errorDescription:String?) -> Void) -> Void {
let url = NSURL(string: urlString)
let request = NSMutableURLRequest(URL: url!)
let task = session.dataTaskWithRequest(request) { (data, response, error) in
guard let data = data where error == nil else {
completionHandler(success: false,data: nil, errorDescription: error?.localizedDescription)
return
}
completionHandler(success: true, data: data, errorDescription: nil)
}
task.resume()
}
可在tableCell/collectionCell中使用,如下所示:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let photo = fetchedResultsController.objectAtIndexPath(indexPath) as! Photo
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! AlbumCell
cell.backgroundColor = UIColor.grayColor()
cell.imageView.image = UIImage(named: "placeholder")
if let image = photo.image {
cell.imageView.image = image
} else {
VTClient.sharedInstance().getImage(photo.url) { (success:Bool, data:NSData?, errorDescription:String?) in
if success {
dispatch_async(dispatch_get_main_queue()) {
let image = UIImage(data: data!)
cell.imageView.image = image
FlickrClient.Caches.imageCache.storeImage(image, withIdentifier: photo.id)
}
}
}
}
return cell
}
}
有关如何使用此功能的更多信息,请参见我的项目。您需要研究单元重用。您将单元格上的图像视图设置为特定图像,然后当您滚动该单元格时,该单元格将被重新使用,因此现在有不正确的图像。将数据图像与UI单元格分开,只需从数据中刷新单元格即可。indexpath代码中的行单元格是正确的。您只需要将图像下载到后台线程中。使用这个库。它将在后台加载图像,并缓存您的图像。例如:image.sd_setImagewith:URLstring:NSURL,占位符image:uiImageName:我不需要使用库来下载图像让session=urlsession.shared。这段代码是一个比较老的项目,Swift 2我想,可能需要一些轻微的改动,我应该解释得更好一些。这是我在学习iOS时参与的一个项目,你不需要这些课程。VTClient就是我放getImage函数的地方,你可以把它放在任何地方。这些类是特定于我的项目的。Photo类只是一个数据类,FlickrClient从FlickrAPI获取图像数据。我在该类中使用图像缓存来存储图像,以便更快地加载。您不必这样做,但这将有助于提高性能。如果您想使用我的代码,您需要使用我的代码的部分。我只是展示了我的代码,以显示它将是如何做你没有照片类,你不需要那个部分。显示更新的代码代码代码现在看起来应该可以了,您现在遇到了什么问题?使用此代码:var image=cell.viewWithTag1 as!UIImageView let URLString=imgLink[indepath.row]let imgUrl=URLString:URLString您可以添加printindexPath.row、URLString并查看控制台的输出结果吗
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let photo = fetchedResultsController.objectAtIndexPath(indexPath) as! Photo
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! AlbumCell
cell.backgroundColor = UIColor.grayColor()
cell.imageView.image = UIImage(named: "placeholder")
if let image = photo.image {
cell.imageView.image = image
} else {
VTClient.sharedInstance().getImage(photo.url) { (success:Bool, data:NSData?, errorDescription:String?) in
if success {
dispatch_async(dispatch_get_main_queue()) {
let image = UIImage(data: data!)
cell.imageView.image = image
FlickrClient.Caches.imageCache.storeImage(image, withIdentifier: photo.id)
}
}
}
}
return cell
}
}