如何实现模拟云朵的方块左右平滑循环连续动画?
实现云朵方块无缝循环滚动动画的解决方案
你遇到的问题很典型——直接移动单个容器会导致动画结束后跳回起点,没法形成自然的无缝循环。其实用两个完全相同的容器视图就能完美解决这个问题,下面是具体的实现步骤和代码:
步骤1:准备两个容器视图
- 在Storyboard中添加两个容器视图(比如命名为
containerView1和containerView2) - 给它们设置完全相同的布局约束,让两者在初始状态下完全重叠
- 重要提醒:containerView2不能是containerView1的子视图,必须放在和containerView1同一层级的父视图下
步骤2:修改动画逻辑
核心思路是让两个容器连续向右移动,当第一个容器完全移出屏幕右侧时,第二个容器刚好衔接上屏幕,利用动画的重复属性实现无缝循环。修改后的代码如下:
class ViewController: UIViewController { // 两个完全相同的容器,用于实现无缝循环 @IBOutlet weak var containerView1: UIView! @IBOutlet weak var containerView2: UIView! override func viewDidLoad() { super.viewDidLoad() // 初始化时将containerView2放在containerView1的右侧,实现无缝衔接 let containerWidth = containerView1.frame.width containerView2.frame = CGRect( x: containerView1.frame.origin.x + containerWidth, y: containerView1.frame.origin.y, width: containerWidth, height: containerView1.frame.height ) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) startAnimating() } func startAnimating() { let animationDuration: TimeInterval = 10 UIView.animate(withDuration: animationDuration, delay: 0, options: [.repeat, .curveLinear], animations: { // 让两个容器同时向右移动自身宽度的距离(如果容器和屏幕等宽,也可以用self.view.bounds.width) self.containerView1.center.x += self.containerView1.frame.width self.containerView2.center.x += self.containerView2.frame.width }, completion: nil) } }
原理说明
- 初始状态下,
containerView2紧贴containerView1的右侧,形成一个连续的整体 - 动画过程中,两个容器以匀速向右移动,当
containerView1完全移出屏幕时,containerView2刚好完全进入屏幕 - 因为动画设置了
.repeat属性,一轮动画结束后两个容器会瞬间重置到初始位置,而由于衔接紧密,用户完全察觉不到跳变 - 添加
.curveLinear选项可以让动画速度保持均匀,更贴合云朵缓慢移动的自然效果
额外注意事项
- 确保两个容器内的云朵方块布局完全一致,这样衔接时才不会出现视觉破绽
- 如果你的容器宽度不等于屏幕宽度,一定要用容器自身的宽度来计算初始位置和移动距离,而不是屏幕宽度
内容的提问来源于stack exchange,提问作者Hapeki
相关产品推荐
相关产品推荐

