Изображения в UICollectionView автоматически переворачиваются при прокрутке вниз?

Я работаю с UICollectionView, где я показываю все изображения из библиотеки фотографий телефона.

Когда я нажимаю на любое изображение, изображение переводится и отображается некоторая информация относительно изображения.

Когда пользователь снова нажимает на одно и то же изображение, изображение снова переворачивается и отображается исходное изображение.

Проблема заключается в том, что всякий раз, когда я просматриваю UICollectionView, последнее выбранное изображение автоматически переключается и отображается информация о изображении.

Как остановить эту проблему.

Вот какой код:

- (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewCell *cell1 = [collectionView cellForItemAtIndexPath:indexPath];
        if(old_path!=NULL){
        UICollectionViewCell *cell2 = [collectionView cellForItemAtIndexPath:old_path];
        [UIView transitionFromView:cell2.selectedBackgroundView toView:cell2.contentView duration:0.5 options:UIViewAnimationOptionCurveLinear |UIViewAnimationOptionTransitionFlipFromLeft completion:nil];

    }
if(old_path==indexPath&&flag)
{
  [cell1 setSelected:NO];
  [UIView transitionFromView:cell1.selectedBackgroundView toView:cell1.contentView duration:0.5 options:UIViewAnimationOptionCurveLinear |UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
    flag=FALSE;
}
else{
    [UIView transitionFromView:cell1.contentView toView:cell1.selectedBackgroundView duration:0.5 options:UIViewAnimationOptionCurveLinear |UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
    flag=TRUE;
}
old_path=indexPath;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];
    ALAsset *asset = assets[indexPath.row];
    NSLog(@"Description : %@",[asset description]);
    UIImage *img=[self imageWithImage:[UIImage imageWithCGImage:[asset thumbnail]] convertToSize:CGSizeMake(150, 150)];
    UIView *contents = [[UIView alloc]initWithFrame:cell.bounds];
    contents.backgroundColor = [UIColor colorWithPatternImage:img];

    [cell.contentView addSubview:contents];

    UIView *backgroundView = [[UIView alloc]initWithFrame:cell.bounds];
    backgroundView.backgroundColor = [UIColor yellowColor];
    UIButton *del=[UIButton buttonWithType:UIButtonTypeRoundedRect];
    del.frame= CGRectMake(backgroundView.frame.origin.x+20,     backgroundView.frame.origin.y+20, 100, 40);
    [del setTitle:@"Delete" forState:UIControlStateNormal];
    [del addTarget:self action:@selector(delete) forControlEvents:UIControlEventTouchUpInside];
    [backgroundView addSubview:del];
    UIButton *cancel=[UIButton buttonWithType:UIButtonTypeRoundedRect];
    cancel.frame= CGRectMake(backgroundView.frame.origin.x+20, backgroundView.frame.origin.y+80, 100, 45);
    [cancel setTitle:@"Cancel" forState:UIControlStateNormal];
    [cancel addTarget:self action:@selector(cancel) forControlEvents:UIControlEventTouchUpInside];
    [backgroundView addSubview:cancel];

    cell.selectedBackgroundView = backgroundView;
    [cell bringSubviewToFront:cell.selectedBackgroundView];
    return cell;
}

Здесь old_path содержит индекс последнего выбранного изображения.

Ответ 1

Основная проблема, вероятно, связана с методами перехода UIView:

[UIView transitionFromView:cell1.selectedBackgroundView toView:cell1.contentView duration:0.5 options:UIViewAnimationOptionCurveLinear |UIViewAnimationOptionTransitionFlipFromLeft completion:nil];

UICollectionViewCell contentView и selectedBackgroundView не следует путать с этим, потому что ячейка управляет их компоновкой. Этот код полностью удалит представление содержимого и заменит его фоном, который, как ожидается, будет находиться за просмотром содержимого при его выборе и удаляется из иерархии представления, если он не выбран.

Правильный способ выполнить то, что вы делаете (показывая/скрывая изображение в ответ на нажатие), будет выполнять переход между самим представлением изображения и другим подвью в представлении содержимого.


Также может быть что-то в вашем коде изменения размера, который переворачивает изображение, но его трудно сказать без кода для imageWithImage:convertToSize:. Вероятно, было бы более эффективно избавиться от этого метода и сделать что-то вроде этого:

UIImageView *imageView = [[UIImageView alloc] initWithFrame:cell.bounds];
imageView.contentsMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
imageView.image = [UIImage imageWithCGImage:[asset thumbnail]];
[cell.contentsView addSubview:imageView];

Несколько других наблюдений:

Ячейки просмотра коллекции повторно используются, что означает, что ваша реализация collectionView:cellForItemAtIndexPath: может привести к добавлению целой кучи представлений изображений в ячейку, которая несколько раз была удалена. Лучшим решением будет подкласс UICollectionViewCell и добавить пользовательские представления в свой метод init.

Код old_path==indexPath на самом деле не проверяет равенство между двумя указательными путями, просто если две переменные имеют один и тот же адрес в памяти. Вместо этого используйте [oldPath isEqual:indexPath].

Ответ 2

Вы не можете выполнять пользовательские анимации в фоновых представлениях без подкласса и обработки явно. Поскольку в представлении коллекции автоматически отображается selectedBackgroundView, если selectedBackgroundView не совпадает с backgroundView. Добавление документации для Apple для справки.

// The background view is a subview behind all other views.
// If selectedBackgroundView is different than backgroundView, it will be placed above the background view and animated in on selection. 

https://developer.apple.com/library/iOs/documentation/UIKit/Reference/UICollectionViewCell_class/Reference/Reference.html