Ios 滚动期间重复使用UICollectionViewCells
我有个问题 我有一个简单的UICollectionView,有一个静态的200个单元格,可以从Flickr加载图像 我的CellForItemAtIndexPath如下所示:Ios 滚动期间重复使用UICollectionViewCells,ios,iphone,uikit,uicollectionview,uicollectionviewcell,Ios,Iphone,Uikit,Uicollectionview,Uicollectionviewcell,我有个问题 我有一个简单的UICollectionView,有一个静态的200个单元格,可以从Flickr加载图像 我的CellForItemAtIndexPath如下所示: - (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [cv dequeueReus
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"FlickrCell" forIndexPath:indexPath];
cell.backgroundColor = [self generateRandomUIColor];
if(![[cell.subviews objectAtIndex:0] isKindOfClass:[PFImageView class]])
{
NSURL *staticPhotoURL = [self.context photoSourceURLFromDictionary:[self.photos objectAtIndex:indexPath.row] size:OFFlickrSmallSize];
PFImageView *imageView = [[PFImageView alloc] initWithFrame:CGRectMake(0, 0, cell.frame.size.height, cell.frame.size.width) andImageURL:staticPhotoURL andOwningCell:cell];
[cell addSubview:imageView];
}
return cell;
}
PFImageView是UIImageView
的一个子类,它在后台线程上加载Flickr照片URL,然后在主线程上更新它自己的图像-这很好
逻辑非常简单——如果没有一个可排队的单元,我就创建一个单元
如果单元格(我希望它已退出队列,并且已经有一个PFImageView)没有PFImageView,我为该单元格分配并初始化一个imageView,并将其添加为单元格的子视图
因此,我希望如果单元格已出列,它应该已经有一个PFImageView作为子视图,并且我们不应该进入if语句来创建一个新的imageView并启动一个新的照片下载请求
相反,我看到的是,UICollectionView顶部和底部的单元格瞬间“离开屏幕”——当它们回到屏幕上时,它们没有被重用,似乎创建了一个新的单元格并刷新了图片
1) 创建单元格后如何获得静态图像(即当单元格稍微离开屏幕时不刷新)
2) 为什么电池没有被重复使用
非常感谢你的时间
约翰我不确定这个电池是否被重复使用。它可能被重用,但子视图可能不存在。我的建议是创建一个PFImageViewCollectionViewCell类(UICollectionViewCell的子类),并将其注册为CollectionView单元格,然后重试。如果我需要单元格内的子视图,我会这样做。我不确定单元格是否被重复使用。它可能被重用,但子视图可能不存在。我的建议是创建一个PFImageViewCollectionViewCell类(UICollectionViewCell的子类),并将其注册为CollectionView单元格,然后重试。如果我需要单元格内的子视图,我会这样做。我发现了几个潜在问题:
// solve problem 2
[self.collectionView registerClass:[UICollectionViewCell class] forReuseIdentifer:@"FlickrCell"];
在collectionView中:cellForItemAtIndexPath
UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"FlickrCell" forIndexPath:indexPath];
cell.backgroundColor = [self generateRandomUIColor];
// solve problem 1 by looking in the contentView for your subview (and looping instead of assuming at 0)
PFImageView *pfImageView = nil;
for (UIView *subview in cell.contentView.subviews)
{
if ([subview isKindOfClass:[PFImageView class]])
{
pfImageView = (PFImageView *)subview;
break;
}
}
NSURL *staticPhotoURL = [self.context photoSourceURLFromDictionary:[self.photos objectAtIndex:indexPath.row] size:OFFlickrSmallSize];
if (pfImageView == nil)
{
// No PFImageView, create one
// note the use of contentView!
pfImageView = [[PFImageView alloc] initWithFrame:CGRectMake(0, 0, cell.contentView.frame.size.height, cell.frame.size.width) andImageURL:staticPhotoURL andOwningCell:cell.contentView];
[cell.contentView addSubview:pfImageView];
}
else
{
// Already have recycled view.
// need to reset the url for the pfImageView. (Problem 3)
// not sure what PFImageView looks like so this is an e.g. I'd probably remove the
// URL loading from the ctr above and instead have a function that loads the
// image. Then, you could do this outside of the if, regardless of whether you had
// to alloc the child view or not.
[pfImageView loadImageWithUrl:staticPhotoURL];
// if you really only have 200 static images, you might consider caching all of them
}
return cell;
对于不太简单的情况(例如,我希望直观地布置单元格,或者在内容中有多个子元素),我通常使用Interface Builder自定义UICollectionViewCell
@property(非原子,赋值)ibuiimageview*image代码>
我看到了几个潜在的问题:
// solve problem 2
[self.collectionView registerClass:[UICollectionViewCell class] forReuseIdentifer:@"FlickrCell"];
在collectionView中:cellForItemAtIndexPath
UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"FlickrCell" forIndexPath:indexPath];
cell.backgroundColor = [self generateRandomUIColor];
// solve problem 1 by looking in the contentView for your subview (and looping instead of assuming at 0)
PFImageView *pfImageView = nil;
for (UIView *subview in cell.contentView.subviews)
{
if ([subview isKindOfClass:[PFImageView class]])
{
pfImageView = (PFImageView *)subview;
break;
}
}
NSURL *staticPhotoURL = [self.context photoSourceURLFromDictionary:[self.photos objectAtIndex:indexPath.row] size:OFFlickrSmallSize];
if (pfImageView == nil)
{
// No PFImageView, create one
// note the use of contentView!
pfImageView = [[PFImageView alloc] initWithFrame:CGRectMake(0, 0, cell.contentView.frame.size.height, cell.frame.size.width) andImageURL:staticPhotoURL andOwningCell:cell.contentView];
[cell.contentView addSubview:pfImageView];
}
else
{
// Already have recycled view.
// need to reset the url for the pfImageView. (Problem 3)
// not sure what PFImageView looks like so this is an e.g. I'd probably remove the
// URL loading from the ctr above and instead have a function that loads the
// image. Then, you could do this outside of the if, regardless of whether you had
// to alloc the child view or not.
[pfImageView loadImageWithUrl:staticPhotoURL];
// if you really only have 200 static images, you might consider caching all of them
}
return cell;
对于不太简单的情况(例如,我希望直观地布置单元格,或者在内容中有多个子元素),我通常使用Interface Builder自定义UICollectionViewCell
@属性(非原子,赋值)IBOUTLE UIImageView*imag