首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ios中使用Alamofire在collectionView中显示图像

在ios中使用Alamofire在collectionView中显示图像
EN

Stack Overflow用户
提问于 2015-05-30 00:26:13
回答 3查看 1.6K关注 0票数 1

我使用Alamofire库在collectionView的单元格中显示图像,但我的问题是当我向上和向下滚动时,我的CollectionView在单元格中显示错误的图像

这是我用于设置单元格数据的代码片段

代码语言:javascript
复制
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CardViewCell

    let pos = indexPath.item % 5

    var paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = 2.5
    paragraphStyle.alignment = .Right
    paragraphStyle.lineBreakMode = .ByTruncatingTail

    if let text = currentCollection.titles?[indexPath.item] {
        var attrString = NSMutableAttributedString(string: text)
        attrString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range:NSMakeRange(0, attrString.length))
        cell.title.attributedText = attrString
    } else {
        cell.title.text = currentCollection.titles?[indexPath.item]
    }
    if let catId = currentCollection.catIds?[indexPath.item] {
        cell.iconImage.image = UIImage(named: icons[catId-1])
    }

    cell.title.font = UIFont(name: "B Yekan", size: 14)
    cell.title.preferredMaxLayoutWidth = cell.frame.size.width - 48

    cell.iconImage.image = cell.iconImage.image!.imageWithRenderingMode(.AlwaysTemplate)
    cell.iconImage.tintColor = UIColor.whiteColor()

    let imageUrl = currentCollection.urlImages![indexPath.item]

    if let image = currentCollection.imageCache.objectForKey(imageUrl) as? UIImage {
        cell.backImage.image = image
    } else {
        cell.backImage.image = nil

        cell.request = Alamofire.request(.GET, imageUrl).validate(contentType: ["image/*"]).responseImage() {
            (request, _, image, error) in
            if error == nil && image != nil {
                self.currentCollection.imageCache.setObject(image!, forKey: request.URLString)

                cell.backImage.image = image
            }
        }
    }


    cell.layer.shadowPath = UIBezierPath(roundedRect: cell.bounds, cornerRadius: cell.layer.cornerRadius).CGPath

    if indexPath.item == currentCollection.titles!.count-3 {
        currentCollection.page++
        appendTitlesInPage(currentCollection.page)
    }



    return cell
}

能帮我哪里错了吗?请!

EN

回答 3

Stack Overflow用户

发布于 2015-05-30 00:45:07

图像请求需要时间-在这段时间内,请求保留对单元格的引用,并在请求完成后设置单元格的backImage.image。不幸的是,到那时,单元格可能已经滚动到屏幕之外,并且可能在另一个indexPath上被重用,其中的图像是不正确的。相反,您应该使用表视图的cellForItemAtIndexPath方法来获取正确的单元格(如果该单元格不再可见,这将返回nil,这将防止您出错)。

票数 1
EN

Stack Overflow用户

发布于 2015-06-04 02:55:51

编辑:现在我已经开发了一个小的CocoaPods库来无缝地处理这个问题。我建议你使用这个,我已经在几个项目中运行了它,没有任何问题。

https://github.com/gchiacchio/AlamoImage

正如@johnpatrickmorgan所说,问题是:当你滚动单元格时,单元格被重用,当对图像的请求得到响应时,它不再有效(图像和单元格不匹配)。

由于响应时间由网络条件决定,您只能等待响应,但您可以做的是在您知道单元将被重用的时刻取消正在进行的请求。为此,您可以在设置新图像之前放置一个cell.request?.cancel(),如下所示:

代码语言:javascript
复制
let imageUrl = currentCollection.urlImages![indexPath.item]

//Cancel the request in progress (to a wrong image) if any.
cell.request?.cancel()

if let image = currentCollection.imageCache.objectForKey(imageUrl) as? UIImage {
    cell.backImage.image = image
} else {
    cell.backImage.image = nil

    cell.request = Alamofire.request(.GET, imageUrl).validate(contentType: ["image/*"]).responseImage() {
        (request, _, image, error) in
        if error == nil && image != nil {
            self.currentCollection.imageCache.setObject(image!, forKey: request.URLString)

            cell.backImage.image = image
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2015-06-04 03:09:42

看看苹果公司提供的"LazyTableImages“示例应用程序。它有一个UITableView,但它的代码本质上与UICollectionView是一样的,而且你不需要第三方库来做这件事。

代码语言:javascript
复制
IconDownloader *iconDownloader = (self.imageDownloadsInProgress)[indexPath];
    if (iconDownloader == nil) 
    {
        iconDownloader = [[IconDownloader alloc] init];
        iconDownloader.appRecord = appRecord;
        [iconDownloader setCompletionHandler:^{

            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

            // Display the newly loaded image
            cell.imageView.image = appRecord.appIcon;

            // Remove the IconDownloader from the in progress list.
            // This will result in it being deallocated.
            [self.imageDownloadsInProgress removeObjectForKey:indexPath];

        }];
        (self.imageDownloadsInProgress)[indexPath] = iconDownloader;
        [iconDownloader startDownload]; 

与您相关的部分在完成处理程序中,您将在其中使用cellForRowAtIndexPath获取单元格。这(以及相应的集合视图方法)确保您获得了正确的单元格,如果它不在屏幕上,它将返回nil,并且所有内容都会正常降级。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30534544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档