我正在从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
答案 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而不是图像传递给单元格通常不是一个好习惯
您可以尝试通过以下方法之一解决此问题:
nil
imageView
prepareForReuse
中ChrisH
的图像(如建议的那样)
collectionView.reloadItemsAtIndexPaths(indexPaths);
)NSCache
为此
特定细胞。 如果您在实施图片缓存方面需要帮助(使用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}}
希望这有帮助!