iOS上的Material Design圆形进度视图

我在iPhone上经常使用Gmail应用程序,并且我一直喜欢Google用来循环加载电子邮件和/或在向下滑动时刷新的循环进度动画视图。 我说的是“材料设计圆形进度视图”,尤其是不确定的实现,其中圆上的两个点似乎一直在互相追逐。

我决定使用Swift在iOS上实现此功能,然后尝试一下。 您可以在这里找到git repo。 这是一个相当快的实现,我只花了几个小时就完成了。 真的可以改善吗? 可能是。 我将来会重新讨论吗? 当然。

进度视图动画由两个基本部分组成:笔划和旋转。 简而言之,我们有一个视图,我们要添加一个称为“ circularLayer”CAShapeLayer 我们必须确保它没有填充色,并为其定义可见的线宽,因为我们将使用它来绘制圆。

 让CircularLayer = CAShapeLayer() 
CircularLayer.lineWidth = 4.0
CircularLayer.fillColor = nil
layer.addSublayer(circularLayer)

我们需要设置一个圆形的UIBezierPath ,稍后再对其进行动画处理。 这是在视图的layoutSubviews()方法上完成的。 为此,我们计算要绘制的圆的半径并描画一条圆弧路径,并将其添加到circularLayer中。 请注意,起始角度为π/ 2,这是基于对进度视图在Gmail iOS应用上开始和结束的位置的观察。

 让半径=最小值(bounds.width,bounds.height)/ 2 — circleLayer.lineWidth / 2 
 让arcPath = UIBezierPath(arcCenter:CGPointZero,radius:radius,startAngle:CGFloat(M_PI_2),endAngle:CGFloat(M_PI_2 +(2 * M_PI)),顺时针:true) 
  CircularLayer.path = arcPath.CGPath 

好的,让我们来看看实现的内容。 现在我们有了中风的道路,但我们需要对其进行动画处理。 我们使用strokeEnd从点0.0到1.0进行动画处理。 我们还将动画添加到strokeStart中 ,以稍稍延迟地赶上移动点。 对于最后的触摸,我们使用具有EastIn和EaseOut时序的动画曲线,以突出显示“追赶”效果。

 让inAnimation:CAAnimation = { 
让动画= CABasicAnimation(keyPath:“ strokeEnd”)
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = 1.0
animation.timingFunction = CAMediaTimingFunction(名称:kCAMediaTimingFunctionEaseIn)
 返回动画 
}()

let outAnimation:CAAnimation = {
让动画= CABasicAnimation(keyPath:“ strokeStart”)
animation.beginTime = 0.5
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = 1.0
animation.timingFunction = CAMediaTimingFunction(名称:kCAMediaTimingFunctionEaseOut)

返回动画
}()

诀窍是, strokeEnd首先运行,并从绘制初始点到整个圆的弧开始。 稍有延迟, strokeStart动画就会开始播放并尝试赶上。 通过查看CAShapeLayer上的Apple文档 我们看到这两个属性具有相反的默认值。 这很明显,因为一个定义了笔画开始的点,另一个定义了笔画结束的点。 当strokeStart开始时,由于其延迟的绘制,它拾取了弧的另一端并推到值1.0,这是路径的终点。

我们需要对这两个动画进行分组,以便进行正确的计时和持续时间计算:

 让strokeAnimationGroup = CAAnimationGroup() 
strokeAnimationGroup.duration = 1.0 + outAnimation.beginTime
strokeAnimationGroup.repeatCount = 1
strokeAnimationGroup.animations = [inAnimation,outAnimation]
strokeAnimationGroup.delegate =自我

以上所有步骤完成后,您将看到此内容。

请注意,我们还有一系列Google品牌颜色,并且会在动画过程中来回更改笔触颜色,但由于它非常简单,因此我们不会在此处复制该代码。

此时,仅剩一步。 我们需要向circularLayer中添加旋转动画,以完整地实现圆形进度视图的可视化实现。 我们为transform.rotation.z键路径添加CABasicAnimation并使其无限旋转(不是真的,但MAXFLOAT是一个很大的数字),其旋转速度比主要动画要慢一点,因此笔划不会同时发生总是指向:

 让rotationAnimation:CAAnimation = { 
让动画= CABasicAnimation(keyPath:“ transform.rotation.z”)
animation.fromValue = 0.0
animation.toValue = 2 * M_PI
animation.duration = 2.0
animation.repeatCount = MAXFLOAT
 返回动画 
}()

而已! 这是模拟器上最终视图的外观:

请确保您在此处签出代码,并让我知道您的想法。