Подтвердить что ты не робот

Выбор ячейки UICollectionview

я сделал сетку изображений, и для того, чтобы показать ее выбор, я выделил границу для изображения, когда он был выбран. но проблема заключается в том, что я выбираю какое-то изображение сверху и прокручиваю сетку изображений, а другое изображение внизу также было выбрано. ниже мой фрагмент кода:

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

Я мог догадаться, что что-то не так, повторное использование ячейки, но не уверенно и не может решить проблему. Ожидание любой помощи и предложений.

Спасибо заранее.

4b9b3361

Ответ 1

Я не понимаю, почему это произойдет. Я не считаю, что проблема заключается в использовании row vs item, хотя вы действительно должны использовать item. Я могу представить, однако, если в вашем представлении коллекции больше одного section, то поиск только row/item, но игнорирование section будет проблемой (т.е. Он будет выбирать один и тот же номер item в каждый section).

Чтобы разрезать гордиев узел, я предлагаю сохранить NSIndexPath выбранного элемента, а затем использовать его для сравнения. Это также упрощает оптимизацию в 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 the same as the one we just tapped on, then we're unselecting it

            self.selectedItemIndexPath = nil;
        }
        else
        {
            // if it 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 (я не вижу в этом никакого значения). Также обратите внимание, что вместо того, чтобы перезагружать весь просмотр коллекции, я только перезагружаю выбранную ячейку (и если была предыдущая выбранная ячейка, она тоже), которая должна быть более эффективной.

Ответ 2

Этот код находится в 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