Swift中如何为UICollectionView的每个cell配置不同的Lottie动画
解决UICollectionView Cell展示不同Lottie动画的方案
原有代码的核心问题
- 直接重新赋值Storyboard关联的
animationView实例,原Storyboard中配置的视图约束、层级关系全部失效 - 新创建的Lottie动画视图没有添加到cell的视图层级中,注释掉的
view.addSubview是错误添加到了当前控制器的视图上,不是cell的contentView - 没有处理cell复用逻辑,滚动时会出现动画错乱、多个动画重叠的问题
- 用
view.bounds设置动画视图frame会导致尺寸和cell不匹配,不同设备适配异常
调整实现步骤
方案1:保留Storyboard关联的Lottie视图(推荐)
你不需要在Storyboard中指定固定动画名称,只需要预留animationView的IBOutlet关联,将其约束设置为铺满cell的contentView即可,不要重新初始化关联的animationView实例,仅动态替换animation属性即可。
自定义cell的关联代码参考:
import Lottie class WorkOutCollectionViewCell: UICollectionViewCell { // Storyboard关联的Lottie动画视图 @IBOutlet weak var animationView: LottieAnimationView! }
方案2:纯代码创建动画视图(无需Storyboard配置)
如果不想用Storyboard关联,可以在自定义cell的初始化方法里创建动画视图,添加自动布局约束铺满contentView,代码参考:
import Lottie class WorkOutCollectionViewCell: UICollectionViewCell { let animationView: LottieAnimationView = { let view = LottieAnimationView() view.translatesAutoresizingMaskIntoConstraints = false view.contentMode = .scaleAspectFit view.loopMode = .loop view.animationSpeed = 0.5 return view }() override init(frame: CGRect) { super.init(frame: frame) setupView() } required init?(coder: NSCoder) { super.init(coder: coder) setupView() } private func setupView() { contentView.addSubview(animationView) NSLayoutConstraint.activate([ animationView.topAnchor.constraint(equalTo: contentView.topAnchor), animationView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), animationView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), animationView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) ]) } }
修正后的cellForItemAt代码
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) guard let workCell = cell as? WorkOutCollectionViewCell else { return cell } // 先停止旧动画,避免cell复用时出现动画错乱 workCell.animationView.stop() // 动态加载对应位置的动画资源 workCell.animationView.animation = LottieAnimation.named(workout[indexPath.row]) // 播放新动画 workCell.animationView.play() return workCell }
如果动画的通用属性(循环模式、播放速度等)没有动态修改需求,直接在Storyboard或者自定义cell的初始化代码里配置即可,不需要在cellForItemAt里重复赋值。
内容的提问来源于stack exchange,提问作者Adir Sharon
相关产品推荐
相关产品推荐

