UICollectionViewController会暂时向我显示错误的图像,然后刷新到正确的图像

时间:2015-09-23 17:04:05

标签: ios swift uicollectionview uicollectionviewcell

我正在从JSON响应创建一个集合视图。 Json响应具有高分辨率图像和大约2000年的图像数量。由于数据来自第三方,我无法控制图像大小。

实现:

JSON示例:

{
    "imagelist": [
        {
            "largeImage": "https://amazingphotos/01.jpg"
        },
        {
            "largeImage": "https://amazingphotos/02.jpg"
        },
}

在UICollectionViewController中访问JSON:

Alamofire.request(.GET, dataURL)
            .responseJSON { _, _, result in
                if var json:JSON = JSON(result.value!){
                self.imageURLs = json["imagelist"].arrayValue
                self.collectionView?.reloadData()
                }
        }

在cellForItemAtIndexPath中,我将URL传递给单元格而不是图像本身。

let cell = collectionView.dequeueReusableCellWithReuseIdentifier("imageCell", forIndexPath: indexPath) as! CollectionViewCell
        cell.imageData = imageURLs[indexPath.row]

在自定义Cell我只是这样做:

var imageData:SwiftyJSON.JSON?{
        didSet{
            self.setup() 
        }
    }

    func setup(){
        if let imageURLString = self.imageData?["largeImage"]{
            let imageURL = NSURL(string: imageURLString.stringValue)
            self.imageThumbnail.hnk_setImageFromURL(imageURL!)
        }

问题:当我加载集合视图时,它会正确显示图像,一旦我开始滚动它就会在新单元格中显示我之前的图像几秒钟然后刷新。

我多次使用集合视图,但从未使用过如此多的数据。请指教。 TIA

2 个答案:

答案 0 :(得分:7)

滚动收藏视图时所看到的是一个重复使用的单元格,其中包含上一次使用的图像。 prepareForReuse有一个override func prepareForReuse() { myImageView.image = nil super.prepareForReuse() } 函数,可用于将任何子视图设置回默认状态。

                var container = document.getElementById("newsFeed");
                $rootScope.newsEntries = result.feed.entries;
                for (var i = 0; i < result.feed.entries.length; i++) {
                    var entry = result.feed.entries[i];
                    var div = document.createElement("div");
                    var title = document.createElement("h3");
                    title.appendChild(document.createTextNode(entry.title));
                    var content = document.createElement("div");
                    content.innerHTML = entry.content;
                    content.style.width = "100%";
                    content.style.height = "auto";
                    div.appendChild(title);
                    div.appendChild(content);
                    div.appendChild(document.createElement("br"));
                    container.appendChild(div);

答案 1 :(得分:0)

修改
如果您尚未实现缓存,将图像URL而不是图像传递给单元格通常不是一个好习惯 您可以尝试通过以下方法之一解决此问题:

  1. nil imageView prepareForReuseChrisH的图像(如建议的那样) collectionView.reloadItemsAtIndexPaths(indexPaths);
  2. 逐个下载图像并将其存储在数组中。下载图像后,请致电: NSCache为此 特定细胞。
  3. 重构代码并实现图像缓存。
  4. 如果您在实施图片缓存方面需要帮助(使用Objective-C),那么以下@interface MBGalleryViewController () { NSArray* imageUrls; // array of image urls NSCache* cache; } @end @implementation MBGalleryViewController - (void)viewDidLoad { [super viewDidLoad]; cache = [[NSCache alloc] init]; // initialize cache } - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return [imageUrls count]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString* identifier = @"Cell"; MyCollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) { UIImage* image = [cache objectForKey:@(indexPath.item)]; // retrieve image for this indexPath.item if (!image) { // will be true if is not yet cached image = [imageDownloader downloadImageWithURL:imageUrls[indexPath.item]]; // download image from somewhere [cache setObject:image forKey:@(indexPath.item)]; // cache image for this indexPath.item } dispatch_sync(dispatch_get_main_queue(), ^(void) { cell.imageView.image = image; // set image }); }); return cell; } @end 代码可能会给您一个想法:

    cellForItemAtIndexPath

    原帖
    我过去也遇到过类似的问题 这可能是因为ImageView在实际下载图像之前被调用,或者可能是由于图像未在主队列中更新。
    此问题的解决方法是在UICollectionViewCell中为dispatch_async(dispatch_get_main_queue()) { cell.imageView.image = imageURLs[indexPath.row]; }设置默认图片 也可以尝试像这样设置图像:
    {{1}}
    希望这有帮助!