为集合视图快速添加动画效果



您好,我正在尝试为CollectionView制作动画。它需要改变位置 x 和他的宽度。

UIView.animate(withDuration: 1, delay: 0, options: .beginFromCurrentState, animations: {
collectionView.frame = CGRect(x: 500, y: 0, width: 1000, height: 700)
})

但问题是单元格中的图像不会调整大小,我认为单元格也是如此。 你有解决方案吗?

  1. 创建一个简单的自定义流布局。
  2. 将此流布局类分配给情节提要中的集合视图。

    class CustomFlowLayout: UICollectionViewFlowLayout {
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
    return true
    }
    }
    

    而且对约束进行动画处理比对帧进行动画处理更好。为此:

  3. 制作宽度和前导约束的出口。
  4. 在 UIView 动画块中更改它们的常量。
  5. 不要忘记在动画块的末尾调用self.layoutIfNeed((。

UICollectionViewCell 大小与 parrent UICollectionView 的框架无关。

也许您实际上可以"放大"图层

var transformation = CGAffineTransform.identity
let translate = CGAffineTransform(translationX: 2, y: 2)
let scale = CGAffineTransform(scaleX: 2, y: 2)
transformation = scale.concatenating(translate)
UIView.animate(withDuration: 0.15, animations: {
self.collectionView.transform = transformation
})

也许无效布局调用可以帮助您。 此外,您是否正在使用自定义流布局

在视图控制器中,如果您使用的是情节提要,请使用 IBOutlet 连接UICollectionviewFlowLayout(在我的示例中为collectionViewFlowLayout(,将集合视图宽度约束(在我的示例中collectionViewWidth(连接为 IBOutlet,UICollectionView连接为 IBOutlet(在我的示例中collectionView(。您可以使用以下命令同时更改集合视图框架和单元格:

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5, execute: {
self.width = 400
self.height = 400
self.collectionView.performBatchUpdates({
self.collectionViewFlowLayout.invalidateLayout()
self.collectionView.setCollectionViewLayout(self.collectionViewFlowLayout, animated: true)
}, completion: { _ in })
})
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5, execute: {
self.collectionViewWidth.constant = 50
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut,
animations: self.view.layoutIfNeeded, completion: nil)
})

例如,您需要将width和 varheight声明为初始值为 100 的类属性。然后在上面的代码中对此进行更改。由于以下实现,它成为可能。请注意,这需要您采用协议UICollectionViewDelegateFlowLayout

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: width, height: height)
}

最新更新