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将是一个问题(即它将在每个 sectionselect相同的item编号)。

为了削减Gordian结,我build议保存所选项目的NSIndexPath ,然后用它作为比较的基础。 这也使得在didSelectItemAtIndexPath渲染优化变得容易。 无论如何,首先定义你的财产:

 @property (nonatomic, strong) NSIndexPath *selectedItemIndexPath; 

然后实现cellForItemAtIndexPathdidSelectItemAtIndexPath

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