显示图像的简单 UICollectionView 行为奇怪:一些图像显示正确,一些在错误的位置,一些完全丢失 [英] Simple UICollectionView to show images behaves odd: Some Images are displayed correct, some at wrong position, some missing at all
问题描述
我想使用 UICollectionView 在 iPhone 上的网格中显示图像,每行显示 3 张图像.对于简单的测试"(如我所想),我在我的项目中添加了 15 张 JPG 图像,这样它们将在我的包中,我可以通过 [UIImage imageNamed:...] 简单地加载它们.
I want to show images in a grid on iPhone using a UICollectionView, showing 3 images a row. For a "dead simple test" (as I thought), I've added 15 JPG images to my project, so that they'll be in my bundle and I can load them simply via [UIImage imageNamed:...].
我认为我所做的一切都是正确的(设置和注册 UICollectionViewCell 子类,使用 UICollectionViewDataSource 协议方法),但是,UICollectionView 的行为很奇怪:
I think I've done everything correct (setting up & registering UICollectionViewCell subclass, use of UICollectionViewDataSource Protocol methods), however, the UICollectionView behaves very weird:
它仅显示以下模式中的少数图像:第一行显示图像 1 &3,第二行是空白,下一行像第一行一样(图像1和3正确显示),第四行空白,依此类推...
It shows only a few of the images in the following pattern: First line shows image 1 & 3, second line is blank, next line like the first again (image 1 & 3 showing properly), fourth line blank, and so on...
如果我在导航栏中按下触发 [self.collectionView reloadData] 的按钮,随机单元格会出现或消失.让我抓狂的是,这不仅仅是图像是否出现的问题.有时,图像也会在单元格之间交换,即它们出现在 indexPath 中,它们绝对没有连接!
If I push a button in my NavBar that triggers [self.collectionView reloadData], random cells appear or disappear. What drives me nuts is that it's not only an issue of images appear or not. Sometime, images also swap between the cells, i.e. they appear for a indexPath they are definitely not wired up!
这是我的单元格代码:
@interface AlbumCoverCell : UICollectionViewCell
@property (nonatomic, retain) IBOutlet UIImageView *imageView;
@end
@implementation AlbumCoverCell
@synthesize imageView = _imageView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_imageView = [[UIImageView alloc] initWithFrame:frame];
[self.contentView addSubview:_imageView];
}
return self;
}
- (void)dealloc
{
[_imageView release];
[super dealloc];
}
- (void)prepareForReuse
{
[super prepareForReuse];
self.imageView.image = nil;
}
@end
我的 UICollectionViewController 子类的部分代码,其中 'imageNames' 是一个包含所有 jpg 文件名的 NSArray:
Part of the code for my UICollectionViewController subclass, where 'imageNames' is an NSArray holding all jpg filenames:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.collectionView registerClass:[AlbumCoverCell class] forCellWithReuseIdentifier:kAlbumCellID];
}
#pragma mark - UICollectionViewDataSource Protocol methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [self.imageNames count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
AlbumCoverCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kAlbumCellID forIndexPath:indexPath];
NSString *imageName = [self.imageNames objectAtIndex:indexPath.row];
NSLog(@"CV setting image for row %d from file in bundle with name '%@'", indexPath.row, imageName);
cell.imageView.image = [UIImage imageNamed:imageName];
return cell;
}
#pragma mark - UICollectionViewDelegateFlowLayout Protocol methods
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
{
return CGSizeMake(100, 100);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
{
return UIEdgeInsetsMake(0, 0, 0, 0);
}
从 cellForItemAtIndexPath 中的 NSLog 语句:我可以看到所有单元格(不仅仅是显示的单元格)都调用了该方法,并且 indexPath.row 和文件名之间的映射是正确的.
From the NSLog statement in cellForItemAtIndexPath: I can see that the method is called for all of the cells (not only the one's displayed) and that the mapping between indexPath.row and filename is correct.
有人知道什么会导致这种奇怪的行为吗?
Has anybody an idea what could cause this weird behavior?
推荐答案
与此同时,我已经找到了解决方案.这实际上是我的 UICollectionViewCell
子类 AlbumCoverCell
的实现中的一个非常微妙的错误.
In the meantime, I've found the solution. It was actually a very subtle error in the implementation of my UICollectionViewCell
subclass AlbumCoverCell
.
问题是我将单元格实例的框架设置为 UIImageView
子视图的框架,而不是传递单元格的 contentView
的 bounds 属性!
The problem is that I've set the frame of the cell instance as the frame of the UIImageView
subview instead of passing the bounds property of the cell's contentView
!
解决方法如下:
@implementation AlbumCoverCell
@synthesize imageView = _imageView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// WRONG:
// _imageView = [[UIImageView alloc] initWithFrame:frame];
// RIGHT:
_imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds];
[self.contentView addSubview:_imageView];
}
return self;
}
- (void)prepareForReuse
{
[super prepareForReuse];
// reset image property of imageView for reuse
self.imageView.image = nil;
// update frame position of subviews
self.imageView.frame = self.contentView.bounds;
}
...
@end
这篇关于显示图像的简单 UICollectionView 行为奇怪:一些图像显示正确,一些在错误的位置,一些完全丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!