Swift Images放置在错误的单元格中,并在UICollectionview中保持chaging

时间:2017-06-22 09:43:25

标签: swift swift3 uiimageview uicollectionview

我已经搜索了但是我没有成功找到我的问题的答案,我正在从互联网下载图像并将它们放入集合视图但是当我滚动的地方正在改变甚至没有滚动它们放在错误的单元格上这里是我的代码:

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

更新:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)


var image1 = cell.viewWithTag(1) as! UIImageView
    let URLString = imgLink[indexPath.row]
    let imgUrl = URL(string: URLString)


    var Label = cell.viewWithTag(2) as! UILabel
    Label.text = namesArray[indexPath.row]

    getImage(urlString: URLString) { (success:Bool, data:NSData?, errorDescription:String?) in
        if success {

            DispatchQueue.main.async() {
                let image = UIImage(data: data! as Data)
                image1.image = image

            }
        }
    }
   return cell
}





func getImage(urlString:String, completionHandler:@escaping (_ success:Bool, _ data:NSData?, _ errorDescription:String?) -> Void) -> Void {

    let url = NSURL(string: urlString)
    let request = NSMutableURLRequest(url: url! as URL)
     let session = URLSession.shared
    let task = session.dataTask(with: request as URLRequest) { (data, response, error) in

        guard let data = data, error == nil else {
            completionHandler(false,nil, error?.localizedDescription)
            return
        }

        completionHandler(true, data as NSData?, nil)
    }

    task.resume()

}

1 个答案:

答案 0 :(得分:1)

此函数是一个异步函数,需要一些时间才能完成

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

在此查看我的项目https://github.com/martinjkelly/virtual-tourist/blob/master/Virtual游客,了解有关如何使用

的更多信息