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

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

问题描述

我想使用UICollectionView在iPhone上的网格中显示图像,每行显示3张图像。对于一个死的简单测试(我认为),我已经为我的项目添加了15个JPG图像,因此它们将在我的包中,我只需通过[UIImage imageNamed:...]加载它们。 / p>

我认为我已经做了一切正确的事情(设置和注册UICollectionViewCell子类,使用UICollectionViewDataSource协议方法),但是,UICollectionView表现得非常奇怪:



它只显示以下模式中的一些图像:
第一行显示图像1& 3,第二行是空白,下一行再次像第一行(图1和3显示正确),第四行空白,依此类推......



如果我按下我的NavBar中的一个按钮,触发[self.collectionView reloadData],随机单元格出现或消失。让我疯狂的是,这不仅是图像出现与否的问题。有时,图像也在单元格之间交换,即它们出现在indexPath中,它们绝对没有连线!



这是我的单元格代码:

  @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];
}
返回自我;
}

- (void)dealloc
{
[_imageView release];
[super dealloc];
}

- (无效)prepareForReuse
{
[super prepareForReuse];
self.imageView.image = nil;
}
@end

我的UICollectionViewController子类的部分代码,其中'imageNames'是一个NSArray,包含所有jpg文件名:

   - (void)viewDidLoad 
{
[ super viewDidLoad];
[self.collectionView registerClass:[AlbumCoverCell class] forCellWithReuseIdentifier:kAlbumCellID];
}

#pragma mark - UICollectionViewDataSource协议方法
- (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(@从名为'%@'的包中的文件中的行%d的CV设置图像,indexPath.row,imageName);
cell.imageView.image = [UIImage imageNamed:imageName];

返回单元格;
}

#pragma mark - UICollectionViewDelegateFlowLayout协议方法
- (CGSize)collectionView:(UICollectionView *)collectionView布局:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
{
返回CGSizeMake(100,100);
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView布局:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
{
返回UIEdgeInsetsMake(0,0,0,0);
}

从cellForItemAtIndexPath中的NSLog语句:我可以看到该方法被调用所有单元格(不仅是显示的单元格)以及indexPath.row和文件名之间的映射都是正确的。



有人知道什么可能导致这种奇怪的行为吗?

解决方案

与此同时,我找到了解决方案。在我的 UICollectionViewCell 子类 AlbumCoverCell 的实现中,这实际上是一个非常微妙的错误。



问题是我将单元格实例的框架设置为 UIImageView 子视图的框架,而不是传递单元格的bounds属性 contentView



以下是修复:

  @implementation AlbumCoverCell 
@synthesize imageView = _imageView;

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self){
// WRONG:
// _imageView = [[UIImageView alloc] initWithFrame:frame];

//右:
_imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds];
[self.contentView addSubview:_imageView];
}
返回自我;
}


- (无效)prepareForReuse
{
[super prepareForReuse];

//重置imageView的图像属性以便重用
self.imageView.image = nil;

//更新子视图的帧位置
self.imageView.frame = self.contentView.bounds;
}

...

@end


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:...].

I think I've done everything correct (setting up & registering UICollectionViewCell subclass, use of UICollectionViewDataSource Protocol methods), however, the UICollectionView behaves very weird:

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...

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!

Here is my code for the cell:

@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

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);
}

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?

解决方案

In the meantime, I've found the solution. It was actually a very subtle error in the implementation of my UICollectionViewCell subclass AlbumCoverCell.

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!

Here is the fix:

@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天全站免登陆