UICollectionView 中的图像在向下滚动时会自动翻转?

Posted

技术标签:

【中文标题】UICollectionView 中的图像在向下滚动时会自动翻转?【英文标题】:Images in UICollectionView automatically flips when scrolled down? 【发布时间】:2014-01-31 11:38:26 【问题描述】:

我正在使用 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 包含最后选择的图像的索引。

【问题讨论】:

需要一些代码。我们不知道你在做什么。 cellForItemAtIndexPath: 方法添加代码,以便我们了解您是如何绘制单元格的。 【参考方案1】:

主要问题可能在于 UIView 转换方法:

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

UICollectionViewCellcontentViewselectedBackgroundView 不应该像这样被弄乱,因为单元格管理它们的布局。此代码将完全删除内容视图并将其替换为背景视图,该背景视图在被选中时应位于内容视图的后面,而在未选中时从视图层次结构中删除。

完成您正在做的事情(显示/隐藏图像以响应点击)的正确方法是在图像视图本身和内容视图上的另一个子视图之间执行转换。


您的调整大小代码中也可能有一些东西会翻转图像,但如果没有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】:

如果没有子类化和显式处理,您无法在背景视图上制作自定义动画。因为如果selectedBackgroundViewbackgroundView 不同,集合视图会自动将selectedBackgroundView 置于顶部。添加苹果文档以供参考。

// 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

【讨论】:

以上是关于UICollectionView 中的图像在向下滚动时会自动翻转?的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView在滚动时重新加载错误的图像

将单元格高度固定到 UICollectionView 高度

在 UICollectionView 中显示错误的图像

UIcollectionView 具有缓慢的图像加载和滚动

UICollectionView 检测滚动方向和更改图像

如何使 UICollectionView 的高度可自动调整和滚动?