UICollectionView单元格select
我做了一个图像的网格,为了显示它的select,我画了边界的图像,当select。 但问题是,当我select顶部的图像,并向下滚动图像的网格,底部的其他图像也似乎被选中。 下面是我的代码片段:
UINib *cellNib = [UINib nibWithNibName:@"collectionCell" bundle:nil]; [self.collectionView registerNib:cellNib forCellWithReuseIdentifier:@"cellCV"]; UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; [flowLayout setItemSize:CGSizeMake(95, 95)]; [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical]; [self.collectionView setCollectionViewLayout:flowLayout];
上面已经添加了viewDidLoad与在nib中devise的集合视图单元格。
并实行以下代表:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { selectedImageIndex = indexPath.row; [collectionView reloadData]; } -(CollectionCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UIImage *img = [imageArray objectAtIndex:indexPath.row]; static NSString *cellIdentifier = @"cellCV"; CollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier: cellIdentifier forIndexPath:indexPath]; cell.imageView.image = img; cell.imageView.tag = indexPath.row; UIImageView *imgView = (UIImageView *)[cell viewWithTag:indexPath.row]; if (indexPath.row == selectedImageIndex) { imgView.layer.borderWidth = 4.0; imgView.layer.borderColor = [UIColor redColor].CGColor; NSLog(@"selected indexpath: %d", indexPath.row); } else { imgView.layer.borderWidth = 0.0; imgView.layer.borderColor = nil; } return cell; }
我可以猜测,重用单元格有什么问题,但不知道,并不能解决它的想法。 等待任何forms的帮助和build议。
提前致谢。
我不明白为什么会发生。 我不相信问题是使用row
vs item
,尽pipe你真的应该使用item
。 但是,我可以想象,如果你的集合视图有多个section
,那么只查看row
/ item
而忽略section
将是一个问题(即它将在每个 section
select相同的item
编号)。
为了削减Gordian结,我build议保存所选项目的NSIndexPath
,然后用它作为比较的基础。 这也使得在didSelectItemAtIndexPath
渲染优化变得容易。 无论如何,首先定义你的财产:
@property (nonatomic, strong) NSIndexPath *selectedItemIndexPath;
然后实现cellForItemAtIndexPath
和didSelectItemAtIndexPath
:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"Cell"; CollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; cell.imageView.image = ... if (self.selectedItemIndexPath != nil && [indexPath compare:self.selectedItemIndexPath] == NSOrderedSame) { cell.imageView.layer.borderColor = [[UIColor redColor] CGColor]; cell.imageView.layer.borderWidth = 4.0; } else { cell.imageView.layer.borderColor = nil; cell.imageView.layer.borderWidth = 0.0; } return cell; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { // always reload the selected cell, so we will add the border to that cell NSMutableArray *indexPaths = [NSMutableArray arrayWithObject:indexPath]; if (self.selectedItemIndexPath) { // if we had a previously selected cell if ([indexPath compare:self.selectedItemIndexPath] == NSOrderedSame) { // if it's the same as the one we just tapped on, then we're unselecting it self.selectedItemIndexPath = nil; } else { // if it's different, then add that old one to our list of cells to reload, and // save the currently selected indexPath [indexPaths addObject:self.selectedItemIndexPath]; self.selectedItemIndexPath = indexPath; } } else { // else, we didn't have previously selected cell, so we only need to save this indexPath for future reference self.selectedItemIndexPath = indexPath; } // and now only reload only the cells that need updating [collectionView reloadItemsAtIndexPaths:indexPaths]; }
顺便说一下,请注意,我并没有搞乱tag
属性(我没有看到它的价值)。 还要注意的是,而不是重新加载整个集合视图,我只是重新加载选定的单元格(如果有一个先前选定的单元格,也是一个),应该是更有效的。
这段代码是在Swift 3:
if self.selectedItemIndexPath != nil && indexPath.compare(self.selectedItemIndexPath) == .orderedSame { cell.imageView!.layer.borderColor = UIColor.red.cgColor cell.imageView!.layer.borderWidth = 4.0 } else { cell.imageView!.layer.borderColor = nil cell.imageView!.layer.borderWidth = 0.0 } return cell