Ios UICollectionview单元格选择
我制作了一个图像网格,为了显示它的选择,我在选择时为图像绘制了边框。但问题是,当我选择顶部的一些图像并向下滚动图像网格时,底部的一些其他图像似乎也被选中。下面是我的代码片段:Ios UICollectionview单元格选择,ios,uicollectionview,Ios,Uicollectionview,我制作了一个图像网格,为了显示它的选择,我在选择时为图像绘制了边框。但问题是,当我选择顶部的一些图像并向下滚动图像网格时,底部的一些其他图像似乎也被选中。下面是我的代码片段: UINib *cellNib = [UINib nibWithNibName:@"collectionCell" bundle:nil]; [self.collectionView registerNib:cellNib forCellWithReuseIdentifier:@"cellCV"]; UICollectio
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中设计
并落实了以下代表:
-(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;
}
我可以猜到重复使用电池出了问题,但我不确定,也没有办法解决它。
等待任何帮助和建议
提前谢谢。我不明白为什么会发生这种情况。我认为问题不在于使用
行
与项
,尽管您确实应该使用项
。但是,我可以想象,如果集合视图有多个节
,那么只查看行
/项
,而忽略节
将是一个问题(即,它将在每个节
中选择相同的项
编号)
为了解决这个棘手的问题,我建议保存所选项目的nsindepath
,然后使用它作为比较的基础。这也使得在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];
}
顺便说一句,请注意,我并不是在乱搞
标记
属性(我看不出它有什么价值)。还要注意的是,我不是重新加载整个集合视图,而是只重新加载所选单元格(如果有以前选择的单元格,也要重新加载该单元格),这应该会更有效。此代码在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
尝试使用indexPath.item代替indexPath.row。如果您仍然面临任何问题,请告诉我谢谢您的建议Anurag,但indexath.item的工作方式与indexpath.row相同……嗨,Rob,这就像任何事情一样。。你的解决方案清晰明了,消除了我的许多困惑,即使是在tableview方面。。谢谢!!伟大的您好,当我在collection视图中选择其他单元格时,DidDescelectItemAtIndexPath似乎没有被调用。我正试图在didDeselectItemAtIndexPath中做一些变通,因为当我双击单元格取消选择它时,上面的代码崩溃了。我确信我已正确设置了代表。有什么解决方案可以避免此崩溃或调用collectionview friends的“取消选择”委托吗?@XiOS您只需在再次点击同一项目时将
didSelectItemAtIndexPath
更改为处理。请参阅修改后的答案。Rob,这是处理UICollectionView上的选择的最动态的方式吗?选择“单元格”时会发生什么情况。从其余单元格中手动删除“所选内容”?或者这也是一个重用问题?我不知道我是否错了,但是框架应该为我做这件事,但是你的解决方案按照我的意愿工作,谢谢!!!罗布。