如何在UICollectionViewCell中为UIView设置动画?

时间:2018-01-06 19:23:20

标签: ios swift uiview uicollectionviewcell uiviewanimation

我创建了一个自定义UICollectionViewCell,它包含一个名为animView的子视图,我打算对其进行动画处理。 animView的形状是一个常规的垂直矩形。

configureCell()方法中,我使用下面的代码配置单元格并创建动画,但我看不到动画。

animView.transform = CGAffineTransform(scaleX: 1.0, y: 0.5)
self.layoutIfNeeded()

UIView.animate(withDuration: 0.7, delay: 0, options: [.curveEaseOut], animations: {
    self.animView.transform = CGAffineTransform.identity
    self.layoutIfNeeded()
}, completion: nil)

然而,当我尝试为整个细胞制作动画时,我看到细胞成功动画。

self.transform = CGAffineTransform(scaleX: 1.0, y: 0.5)
self.layoutIfNeeded()

UIView.animate(withDuration: 0.7, delay: 0, options: [.curveEaseOut], animations: {
    self.transform = CGAffineTransform.identity
    self.layoutIfNeeded()
}, completion: nil)

感谢您的时间和回答。

修改

根据建议,我改变了我调用动画的位置,如下所示。现在,当我尝试为整个单元设置动画时,它正在工作。但是,我想动画animView,它是自定义UICollectionViewCell(BarCell)的子视图。但它不是动画。有什么想法吗?

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {

    let cells = collectionView.visibleCells
    for cell in cells {
        let current = cell as! BarCell
        let curAnimView = current.animView

        curAnimView?.transform = CGAffineTransform(translationX: 0, y: current.animFillHeightCons.constant)
        UIView.animate(withDuration: 0.7) {
            curAnimView?.transform = CGAffineTransform.identity
        }

    }
}

2 个答案:

答案 0 :(得分:1)

您需要仅为可见单元格启动动画。 这是你如何做到的。

添加此

  

UIScrollViewDelegate

它将提供方法

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
            let cells = colAnim.visibleCells
            for cell in cells
            {
                let current = cell as! testCollectionViewCell
                UIView.animate(withDuration: 2.0, animations: {
                    current.animView.transform = CGAffineTransform(translationX: -400, y: 0)
                //Change this animation
                })
            }
        }

同时也要确保这样做。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "testCollectionViewCell", for: indexPath) as! testCollectionViewCell
        cell.animView.transform = CGAffineTransform(translationX: 0, y: 0)// This one
        return cell
    }

通过这样做,您只有在单元格可见时才能实现动画。 感谢。

答案 1 :(得分:0)

有两个条件可以实现:

  1. 您需要重置为每个单元格绑定设置动画的属性
  2. 只有在单元格即将可见时才需要开始动画

此外,也有例外(比如我的情况),有时单元格绑定或集合的布局很复杂或自定义,因此在这些情况下,我们将不得不延迟动画以使其真正起作用。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
 // your dequeue code...
 // ...

 // Reseting your properties as described in 1
 cell.myImageView.alpha = 1
}

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
 let myCell = cell as! MyCell
 // As described in 2
 myCell.animate()
}


class MyCell: UICollectionViewCell {
 func animate() {
  // Optional: As described above, if your scene is custom/complex delaying the animation solves it though it depends on your code
  DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        // Animation code
        UIView.animate(withDuration: 1,
                       delay: 0,
                       options: [.autoreverse, .repeat]) {
            self.seenNotSeenImageView.alpha = 0.5
        }
  }
 }
}

还有第三个条件: 如果您的单元格将被另一个 VC 覆盖,您将需要在包含 collectionView 的 VC 的 viewWillAppear 中启动如下相同的 animated() 方法:

 collectionView.visibleCells.forEach{($0 as? MyCell)?.animate()}