CollectionView 是IOS开发中的很常用的一个控件。
在填充单元格时有两种方式:一个是通过注册类,另一个是使用NIB(注册XIB文件)。
在视图加载事件中调用相应的注册单元格代码。registerClass与registerNib两种的区别官方文档里这样描述:
// For each reuse identifier that the collection view will use, register either a class or a nib from which to instantiate a cell.
// If a nib is registered, it must contain exactly 1 top level object which is a UICollectionViewCell.
// If a class is registered, it will be instantiated via alloc/initWithFrame:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//self.navigationController.navigationBar.backgroundColor=[UIColor blackColor];
[self.collectionView registerClass:[Cell class] forCellWithReuseIdentifier:KCELLID];
[self.collectionView registerNib:[UINib nibWithNibName:@"cell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:KCELLID];
}
然后在实现数据委托事件中编写代码,这里写的代码不需要改变,只是在视图加载事件中写上相应的注册单元格方式代码。
#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;{
return 32;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Cell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:KCELLID forIndexPath:indexPath];
//Cell *cell=collectionView registerNib:<#(UINib *)#> forCellWithReuseIdentifier:<#(NSString *)#>
//NSInteger itemRow=indexPath.item;
// make the cell's title the actual NSIndexPath value
cell.label.text = [NSString stringWithFormat:@"{%d,%d}",indexPath.section,indexPath.item];
// load the image for this cell
NSString *imageToLoad = [NSString stringWithFormat:@"%d",indexPath.item];
cell.image.image = [UIImage imageNamed:imageToLoad];
return cell;
}
#pragma mark -UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
}
#pragma mark - segue
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:@"showDetail"]) {
DetailViewController *detailVC=segue.destinationViewController;
NSIndexPath *indexpath=[self.collectionView indexPathsForSelectedItems][0];
// load the image, to prevent it from being cached we use 'initWithContentsOfFile'
NSString *imageNameToLoad = [NSString stringWithFormat:@"%d_full", indexpath.item];
UIImage *image =[UIImage imageNamed:imageNameToLoad];
detailVC.image=image;
}
}
最后是使用是segue方式来响应点击cell时的事件处理。
另外要注意的:
1、dequeueReuseableCellWithIdentifier:与dequeueReuseableCellWithIdentifier:forIndexPath:的区别:
前者不必向tableView注册cell的Identifier,但需要判断获取的cell是否为nil;
后者则必须向table注册cell,可省略判断获取的cell是否为空,因为无可复用cell时runtime将使用注册时提供的资源去新建一个cell并返回
2、自定义cell时,记得将其他内容加到self.contentView 上,而不是直接添加到 cell 本身上
总结:
1.自定义cell时,
若使用nib,使用 registerNib: 注册,dequeue时会调用 cell 的 -(void)awakeFromNib
不使用nib,使用 registerClass: 注册, dequeue时会调用 cell 的 - (id)initWithStyle:withReuseableCellIdentifier:
2.需不需要注册?
使用dequeueReuseableCellWithIdentifier:可不注册,但是必须对获取回来的cell进行判断是否为空,若空则手动创建新的cell;
使用dequeueReuseableCellWithIdentifier:forIndexPath:必须注册,但返回的cell可省略空值判断的步骤。