PullToBounce核心组件解析:BallView与WaveView动画原理

PullToBounce核心组件解析:BallView与WaveView动画原理

【免费下载链接】PullToBounceAnimated "Pull To Refresh" Library for UIScrollView. Inspired by https://dribbble.com/shots/1797373-Pull-Down-To-Refresh项目地址: https://gitcode.com/gh_mirrors/pu/PullToBounce

PullToBounce是一款为UIScrollView打造的动画刷新库,它通过BallView与WaveView两个核心组件实现了极具视觉冲击力的"下拉刷新"效果。本文将深入解析这两个组件的动画原理,帮助开发者理解其工作机制并应用到自己的iOS项目中。

BallView:带动画效果的球形加载指示器

BallView是PullToBounce中负责显示加载状态的核心组件,它通过组合多个CALayer实现了复杂的动画效果。该组件位于项目的PullToBounce/Source/BallView.swift文件中。

核心结构与初始化

BallView的初始化过程中创建了一个可移动的视图容器(circleMoveView)和一个圆形图层(circleLayer):

let circleMoveView = UIView() circleMoveView.frame = CGRect(x: 0, y: 0, width: moveUpDist, height: moveUpDist) circleMoveView.center = CGPoint(x: frame.width/2, y: frame.height + circleSize / 2) self.addSubview(circleMoveView) circleLayer = CircleLayer( size: circleSize, moveUpDist: moveUpDist, superViewFrame: circleMoveView.frame, color: color ) circleMoveView.layer.addSublayer(circleLayer)

这里的circleLayer是一个自定义的CAShapeLayer子类,它包含了一个旋转指示器(spiner),用于在加载过程中显示旋转动画。

动画实现原理

BallView的动画主要包括两个阶段:

  1. 上升动画:当用户下拉触发刷新时,BallView会向上移动指定距离
  2. 旋转动画:上升到指定位置后,内部的SpinerLayer开始旋转,显示加载状态

上升动画通过CABasicAnimation实现位置变化:

func moveUp(_ distance: CGFloat) { let move = CABasicAnimation(keyPath: "position") move.fromValue = NSValue(cgPoint: position) move.toValue = NSValue(cgPoint: CGPoint(x: position.x, y: position.y - distance)) move.duration = upDuration move.timingFunction = timeFunc move.fillMode = CAMediaTimingFillMode.forwards move.isRemovedOnCompletion = false self.add(move, forKey: move.keyPath) }

旋转动画则由SpinerLayer负责,它通过strokeEnd和strokeStart的动画组合实现了一个不断旋转且逐渐绘制的圆环效果:

func animation() { self.isHidden = false let rotate = CABasicAnimation(keyPath: "transform.rotation.z") rotate.fromValue = 0 rotate.toValue = Double.pi * 2 rotate.duration = 1 rotate.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) rotate.repeatCount = HUGE self.add(rotate, forKey: rotate.keyPath) strokeEndAnimation() }

WaveView:实现弹性波浪效果

WaveView是PullToBounce中负责实现下拉时波浪形变效果的组件,其源代码位于PullToBounce/Source/WaveView.swift。

波浪路径生成

WaveView的核心是通过UIBezierPath创建一个可变形的波浪形状。它使用二次贝塞尔曲线(quadCurve)来实现波浪效果:

func wavePath(amountX:CGFloat, amountY:CGFloat) -> CGPath { let w = self.frame.width let h = self.frame.height let centerY:CGFloat = 0 let bottomY = h let topLeftPoint = CGPoint(x: 0, y: centerY) let topMidPoint = CGPoint(x: w / 2 + amountX, y: centerY + amountY) let topRightPoint = CGPoint(x: w, y: centerY) let bottomLeftPoint = CGPoint(x: 0, y: bottomY) let bottomRightPoint = CGPoint(x: w, y: bottomY) let bezierPath = UIBezierPath() bezierPath.move(to: bottomLeftPoint) bezierPath.addLine(to: topLeftPoint) bezierPath.addQuadCurve(to: topRightPoint, controlPoint: topMidPoint) bezierPath.addLine(to: bottomRightPoint) return bezierPath.cgPath }

通过改变topMidPoint的位置,WaveView可以创建不同幅度的波浪形状。

弹性回弹动画

当用户释放下拉操作时,WaveView会执行一个弹性回弹动画,通过CAKeyframeAnimation实现一系列平滑过渡的路径变化:

let values = [ self.wavePath(amountX: positionX, amountY: positionY), self.wavePath(amountX: -(positionX * 0.7), amountY: -(positionY * 0.7)), self.wavePath(amountX: positionX * 0.4, amountY: positionY * 0.4), self.wavePath(amountX: -(positionX * 0.3), amountY: -(positionY * 0.3)), self.wavePath(amountX: positionX * 0.15, amountY: positionY * 0.15), self.wavePath(amountX: 0.0, amountY: 0.0) ] bounce.values = values bounce.duration = bounceDuration

这种"衰减振动"效果模拟了真实物理世界中的弹性行为,使动画更加自然生动。

组件协作流程

PullToBounce的完整动画效果是BallView和WaveView协同工作的结果:

  1. 用户下拉UIScrollView,WaveView根据下拉距离生成相应的波浪形状
  2. 当下拉距离达到阈值时,BallView开始执行上升动画
  3. BallView上升到指定位置后,启动内部的旋转加载动画
  4. 数据加载完成后,BallView执行下降动画回到初始位置
  5. 同时,WaveView执行弹性回弹动画,恢复到初始状态

这种组合动画创造了视觉上的层次感和流畅的用户体验,使简单的刷新操作变得生动有趣。

集成与使用

要在自己的项目中使用PullToBounce,首先需要克隆仓库:

git clone https://gitcode.com/gh_mirrors/pu/PullToBounce

然后将Source目录下的核心文件添加到你的项目中。通过PullToBounceWrapper类可以轻松地为UIScrollView或其子类(如UITableView)添加动画刷新效果。

BallView和WaveView的设计遵循了单一职责原则,使其易于维护和扩展。开发者可以通过修改颜色、大小、动画时长等参数,轻松定制符合自己应用风格的刷新效果。

通过理解这两个核心组件的动画原理,开发者不仅可以更好地使用PullToBounce库,还能从中学习到复杂iOS动画的实现技巧,应用到自己的项目中。

【免费下载链接】PullToBounceAnimated "Pull To Refresh" Library for UIScrollView. Inspired by https://dribbble.com/shots/1797373-Pull-Down-To-Refresh项目地址: https://gitcode.com/gh_mirrors/pu/PullToBounce

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考