我是UICollection View的新手。有些单元格没有显示,如下图所示。这是我设置它的代码,如果有人可以解释为什么有些单元格丢失会很高兴。此外,当我向上和向下滚动时,单元格中的图像会因某种原因而改变(尽管在此屏幕截图中我对所有单元格使用相同的图像)。缺少整个第二行和第四行,并且缺少中间列。目的是使每行的三行图像彼此相邻。谢谢!
UICollectionViewFlowLayout *layout=[UICollectionViewFlowLayout new];
self.collectionView=[[UICollectionView alloc] initWithFrame:Frame(0,225,1080, Denormalize(screenHeight) - 225) collectionViewLayout:layout];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[self.collectionView setBackgroundColor:[UIColor redColor]];
layout.minimumLineSpacing = 0;
layout.minimumInteritemSpacing = 0;
layout.sectionInset = UIEdgeInsetsMake(0,0,0,0);
[self.view addSubview:_collectionView];
#pragma mark - CollectionView delegate
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.allVideos.count;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];
// cell.backgroundColor=[UIColor greenColor];
NSDictionary *video = self.allVideos[indexPath.row];
UIImageView *thumbnail = [UIImageView new];
thumbnail.contentMode = UIViewContentModeScaleAspectFill;
thumbnail.frame = cell.frame;
thumbnail.clipsToBounds = YES;
thumbnail.image = [UIImage imageNamed:@"DefaultAvatar.png"];
// thumbnail.image = video[@"image"];
[cell addSubview:thumbnail];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(self.view.frame.size.width/3, self.view.frame.size.width/3);
}
答案 0 :(得分:3)
这里的一个主要问题是您在cellForItemAtIndexPath中添加UIImageView作为子视图。每次细胞出列时都会运行此方法,而不是每次初始化细胞时都会运行。这意味着每当其中一个单元格像集合滚动时一样呈现时,就会在单元格上的现有图像视图上添加一个新的子视图。这将很快以图形方式导致重大问题,并使用更多内存然后打算。我要做的第一件事是子类UICollectionViewCell并将你的UIImageView添加到子类。然后,您可以在该方法中设置单元格的图像,但在该特定位置添加子视图是一个非常糟糕的主意。
这是我的方法。
首先,创建一个单元子类并公开一个方法来设置图像。
// MyCollectionViewCell.h
#import <UIKit/UIKit.h>
@interface MyCollectionViewCell : UICollectionViewCell
- (void)setImage:(UIImage *)image;
@end
// MyCollectionViewCell.m
#import "MyCollectionViewCell.h"
@interface MyCollectionViewCell ()
@property (strong, nonatomic) UIImageView *imageView;
@end
@implementation MyCollectionViewCell
-(instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setupImageView];
}
return self;
}
- (void)setupImageView
{
UIImageView *imageView = [[UIImageView alloc]init];
imageView.backgroundColor = [UIColor greenColor];
[self addSubview:imageView];
self.imageView = imageView;
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0];
NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0];
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[self addConstraints:@[leading, trailing, top, bottom]];
}
- (void)setImage:(UIImage *)image
{
[self.imageView setImage:image];
}
@end
这里的布局限制是关键。根据我的经验,UICollectionViewCells在初始化时通常会有一个0的框架,这就是为什么你会看到大量的空盒子(新单元格上的UIImageView正在用CGRectZero初始化)。约束将确保当它们最终正确布局时,imageView也将调整自身以适应。
在此之后,注册您的自定义单元类,然后您可以在CollectionViewController
中实现它- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
[cell setImage:[UIImage imageNamed:@"emoji.jpg"]];
// Configure the cell
return cell;
}
这里是明确设置UIImageViewFrame的前后镜头
VS。使用NSLayoutConstraints。
对于它的地狱,这里是如何在cellForItemAtIndexPath中做同样的事情。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
NSInteger viewTag = 1000;
UIImageView *imageView = (UIImageView *)[cell viewWithTag:viewTag];
if (!imageView) {
imageView = [[UIImageView alloc]init];
imageView.tag = viewTag;
[cell addSubview:imageView];
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:cell attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0];
NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:cell attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0];
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:cell attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:cell attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[cell addConstraints:@[leading, trailing, top, bottom]];
}
imageView.image = [UIImage imageNamed:@"emoji.jpg"];
return cell;
}