【问题标题】:Simple UICollectionView to show images behaves odd: Some Images are displayed correct, some at wrong position, some missing at all显示图像的简单 UICollectionView 行为奇怪:一些图像显示正确,一些在错误的位置,一些完全丢失
【发布时间】:2012-11-23 23:54:16
【问题描述】:

我想使用 UICollectionView 在 iPhone 上的网格中显示图像,每行显示 3 张图像。对于“简单的测试”(正如我所想的那样),我在我的项目中添加了 15 张 JPG 图像,这样它们就会在我的包中,我可以通过 [UIImage imageNamed:...] 简单地加载它们。

我认为我所做的一切都是正确的(设置和注册 UICollectionViewCell 子类,使用 UICollectionViewDataSource 协议方法),但是,UICollectionView 的行为很奇怪:

它仅显示以下模式中的少数图像: 第一行显示图像 1 和 3,第二行为空白,下一行与第一行相同(图像 1 和 3 正确显示),第四行空白,依此类推...

如果我在导航栏中按下触发 [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];
    }
    return self;
}

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

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

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

- (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 和文件名之间的映射是正确的。

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

【问题讨论】:

    标签: uiimageview ios6 uicollectionview uicollectionviewcell


    【解决方案1】:

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

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

    解决方法如下:

    @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
    

    【讨论】:

    • 我犯了类似的错误 - 感谢您发布您找到的解决方案!
    • @Tafkadasoh 谢谢!它立即解决了我的问题,我的头开始撞到墙上了..
    • @Tafkadasoh OMG!非常感谢你!也解决了我的问题。这是最小的东西,但它是一个非常烦人的错误。再次感谢您发布此内容。我真的很感激。
    • 太好了,也解决了我的问题。谢谢!
    • @totocaster UIImageView 不是 nilled,它是 UIImageView 的 image 属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多