显示图像的简单 UICollectionView 行为奇怪:一些图像显示正确,一些在错误的位置,一些完全丢失 [英] Simple UICollectionView to show images behaves odd: Some Images are displayed correct, some at wrong position, some missing at all

查看:28
本文介绍了显示图像的简单 UICollectionView 行为奇怪:一些图像显示正确,一些在错误的位置,一些完全丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆