UICollectionview 单元格选择 [英] UICollectionview cell selection

查看:24
本文介绍了UICollectionview 单元格选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经制作了一个图像网格,为了显示它的选择,我在选择时为图像绘制了边框.但问题是当我在顶部选择一些图像并向下滚动图像网格时,底部的一些其他图像似乎也被选中了.以下是我的代码片段:

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

以上已添加到 viewDidLoad 中,并在 nib 中设计了集合视图单元格.

Above has been added in viewDidLoad with the collection view cell designed in 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;    
}

我可以猜到重用单元格出了点问题,但不确定也想不出解决问题的想法.等待任何形式的帮助和建议.

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.

提前致谢.

推荐答案

我不明白为什么会发生这种情况.我不认为问题在于 rowitem 的使用,尽管您确实应该使用 item.不过,我可以想象,如果您的集合视图有多个 section,那么只查看 row/item 而忽略 section 将是一个问题(即它会在 every section 中选择相同的 item 编号).

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. 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 (i.e. it would select the same item number in every section).

要快刀斩乱麻,我建议保存所选项目的NSIndexPath,然后将其用作比较的基础.这也使得在 didSelectItemAtIndexPath 中呈现优化变得容易.无论如何,首先定义你的属性:

To cut the Gordian knot, I'd suggest saving the NSIndexPath of the selected item, and then using that for the basis of comparison. That also makes it easy to render an optimization in didSelectItemAtIndexPath. Anyway, first define your property:

@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 属性(我认为没有任何价值).另请注意,我只是重新加载选定的单元格(如果以前有一个选定的单元格,那也是),而不是重新加载整个集合视图,这应该更有效.

As an aside, note that I'm not messing around with the tag property (I see no value in that). 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.

这篇关于UICollectionview 单元格选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆