UIView的addMotionEffect:在UICollectionViewCell上失去了它的效果

时间:2014-10-16 07:58:42

标签: ios objective-c uicollectionview core-animation caanimation

您可以通过在物理设备上下载并运行此代码来重现该错误:https://github.com/Hoya/RCCPeakableImageView

它是通过UIImageView子类为图像添加视差效果的。尝试克隆,构建项目,如果您倾斜/平移手机,图像将稍微动画以产生视差效果。

UIImageView子类创建一个内部UIImageView,其框架略大于自身,并通过UIView的addMotionEffect添加UIInterpolatingMotionEffects:非常简单。

使用UIScrollView和UITableView时效果很好,但由于某些原因滚动UICollectionView时,重用的UICollectionViewCells会丢失动作效果。请注意,有趣的是,一旦切换到UIScrollView或UITableView演示并切换回UICollectionView演示,动作效果将再次开始工作。

有解决方法吗?

RCCCollectionViewController

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    RCCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
    static NSString *identifier = @"Cell";
    RCCPeakableCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier
                                                                           forIndexPath:indexPath];
    [cell.imageView setImage:appDelegate.images[indexPath.row]];
    [cell.imageView setPadding:CGPointMake(20.f, 20.f)];

    return cell;
}

RCCPeakableCollectionViewCell

@interface RCCPeakableCollectionViewCell : UICollectionViewCell
@property (nonatomic, weak) IBOutlet RCCPeakableImageView *imageView;
@end

1 个答案:

答案 0 :(得分:2)

您的代码中存在问题:

[cell.imageView setImage:appDelegate.images[indexPath.row]];
[cell.imageView setPadding:CGPointMake(20.f, 20.f)];

此处,setImage:会在图片视图中添加一些动作效果,然后setPadding:会再次添加这些效果。

我在RCCPeakableImageView类上做了一些修改,将运动效果代码添加到layoutSubviews,并且在重用的UICollectionViewCell上运行正常。以下是更新的代码:

- (void)setImage:(UIImage *)image
{
  // Store image
  self.RCC_imageView.image = image;

  [self setNeedsLayout];
}

- (void)setPadding:(CGPoint)padding
{
  // Store padding value
  _padding = padding;

  [self setNeedsLayout];
}

- (void)layoutSubviews
{
  [super layoutSubviews];

  // Remove exising motion effects
  for (UIMotionEffect *effect in [self.RCC_imageView motionEffects]) {
    [self.RCC_imageView removeMotionEffect:effect];
  }

  // Add motion effects if there is any image.
  UIImage *image = self.RCC_imageView.image;
  if (image) {
    // code that add motion effects
    // ...
  }
}