简体   繁体   English

UICollectionview单元格选择

[英]UICollectionview cell selection

i have made a grid of images and in order to show its selection i drew border for the image when selected. 我制作了一个图像网格,为了显示其选择,我在选择时为图像绘制了边框。 but the problem is when i select some image at the top and scroll down the grid of images, some other image at the bottom also seemed to be selected. 但问题是当我在顶部选择一些图像并向下滚动图像网格时,底部的其他一些图像似乎也被选中。 below is my code snippet: 下面是我的代码片段:

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];

Above has been added in viewDidLoad with the collection view cell designed in nib. 上面已添加到viewDidLoad中,其中集合视图单元格设计为nib。

and implemented following delegates: 并实施以下代表:

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

i could guess that something is going wrong with reusing the cell, but not sure and couldnt het an idea to resolve it. 我可以猜到重复使用单元格会出现问题,但不确定并且无法解决问题。 Waiting for any kind of help and suggestions. 等待任何形式的帮助和建议。

Thanks in advance. 提前致谢。

I'm not seeing why this would take place. 我不明白为什么会发生这种情况。 I do not believe the issue is the use of row vs item , though you really should use item . 我不相信问题是使用rowitem ,虽然你真的应该使用item I can imagine, though, if your collection view has more than one section , that only looking at row / item but ignoring section would be a problem (ie it would select the same item number in every section ). 但是,我可以想象,如果你的集合视图有多个section ,那么仅查看row / item但忽略section将是一个问题(即它将在每个 section选择相同的item编号)。

To cut the Gordian knot, I'd suggest saving the NSIndexPath of the selected item, and then using that for the basis of comparison. 为了减少Gordian结,我建议保存所选项目的NSIndexPath ,然后使用它作为比较的基础。 That also makes it easy to render an optimization in didSelectItemAtIndexPath . 这也使得在didSelectItemAtIndexPath呈现优化变得容易。 Anyway, first define your property: 无论如何,首先定义你的财产:

@property (nonatomic, strong) NSIndexPath *selectedItemIndexPath;

And then implement cellForItemAtIndexPath and didSelectItemAtIndexPath : 然后实现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];
}

As an aside, note that I'm not messing around with the tag property (I see no value in that). 顺便说一句,请注意我并没有搞乱tag属性(我认为没有价值)。 Also note that rather than reloading entire collection view, I'm only reloading the selected cell (and if there was a previous selected cell, that one too), which should be more efficient. 另请注意,我不是重新加载整个集合视图,而是仅重新加载所选单元格(如果还有一个先前选定的单元格,那也应该更高效)。

This code is in Swift 3: 这段代码在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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM