UICollectionview cell selection

前端 未结 2 866
遇见更好的自我
遇见更好的自我 2021-01-31 11:12

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

相关标签:
2条回答
  • 2021-01-31 11:20

    This code is in 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
    
    0 讨论(0)
  • 2021-01-31 11:25

    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).

    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;
    

    And then implement cellForItemAtIndexPath and 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];
    }
    

    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.

    0 讨论(0)
提交回复
热议问题