Ios 如何绘制另一层六边形UIBezier路径并相应设置动画

Ios 如何绘制另一层六边形UIBezier路径并相应设置动画,ios,swift,uibezierpath,cashapelayer,caanimation,Ios,Swift,Uibezierpath,Cashapelayer,Caanimation,我正在寻找一种方法来添加另一层六边形贝塞尔路径,如下所示 我已经能够创建六边形使用贝塞尔路径和动画相应,但我试图添加另一个灰色层贝塞尔路径。我尝试添加多个贝塞尔路径,但不起作用 这就是我取得的成果 这是我的LoaderView课程 class LoaderView: UIView { private let lineWidth : CGFloat = 5 internal var backgroundMask = CAShapeLayer() override init(frame:

我正在寻找一种方法来添加另一层六边形贝塞尔路径,如下所示

我已经能够创建六边形使用贝塞尔路径和动画相应,但我试图添加另一个灰色层贝塞尔路径。我尝试添加多个贝塞尔路径,但不起作用

这就是我取得的成果

这是我的
LoaderView
课程

class LoaderView: UIView {

private let lineWidth : CGFloat = 5
internal var backgroundMask = CAShapeLayer()


override init(frame: CGRect) {
    super.init(frame: frame)
    setUpLayers()
    createAnimation()
}


required init?(coder: NSCoder) {
    super.init(coder: coder)
    setUpLayers()
    createAnimation()
}

func setUpLayers()
{
    backgroundMask.lineWidth = lineWidth
    backgroundMask.fillColor = nil
    backgroundMask.strokeColor = UIColor.blue.cgColor
    layer.mask = backgroundMask
    layer.addSublayer(backgroundMask)
}

func createAnimation()
{
    let animation = CABasicAnimation(keyPath: "strokeEnd")
    animation.fromValue = 0
    animation.duration = 1
    animation.repeatCount = .infinity
    backgroundMask.add(animation, forKey: "MyAnimation")
}

override func draw(_ rect: CGRect) {
    let sides = 6
    let rect = self.bounds
    let path = UIBezierPath()
    
    let cornerRadius : CGFloat = 10
    let rotationOffset = CGFloat(.pi / 2.0)
    
    let theta: CGFloat = CGFloat(2.0 * .pi) / CGFloat(sides) // How much to turn at every corner
    let width = min(rect.size.width, rect.size.height)        // Width of the square
    
    let center = CGPoint(x: rect.origin.x + width / 2.0, y: rect.origin.y + width / 2.0)
    
    // Radius of the circle that encircles the polygon
    // Notice that the radius is adjusted for the corners, that way the largest outer
    // dimension of the resulting shape is always exactly the width - linewidth
    let radius = (width - lineWidth + cornerRadius - (cos(theta) * cornerRadius)) / 2.0
    
    
    // Start drawing at a point, which by default is at the right hand edge
    // but can be offset
    var angle = CGFloat(rotationOffset)
    
    let corner = CGPoint(x: center.x + (radius - cornerRadius) * cos(angle), y: center.y + (radius - cornerRadius) * sin(angle))
    path.move(to: CGPoint(x: corner.x + cornerRadius * cos(angle + theta), y: corner.y + cornerRadius * sin(angle + theta)))
    
    for _ in 0..<sides {
        angle += theta
        
        let corner = CGPoint(x: center.x + (radius - cornerRadius) * cos(angle), y: center.y + (radius - cornerRadius) * sin(angle))
        let tip = CGPoint(x: center.x + radius * cos(angle), y: center.y + radius * sin(angle))
        let start = CGPoint(x: corner.x + cornerRadius * cos(angle - theta), y: corner.y + cornerRadius * sin(angle - theta))
        let end = CGPoint(x: corner.x + cornerRadius * cos(angle + theta), y: corner.y + cornerRadius * sin(angle + theta))
        
        path.addLine(to: start)
        path.addQuadCurve(to: end, controlPoint: tip)
        
    }
    path.close()
    backgroundMask.path = path.cgPath
}}
class LoaderView:UIView{
专用let线宽:CGFloat=5
内部var backgroundMask=CAShapeLayer()
重写初始化(帧:CGRect){
super.init(frame:frame)
setUpLayers()
createAnimation()
}
必需初始化?(编码器:NSCoder){
super.init(编码器:编码器)
setUpLayers()
createAnimation()
}
func setUpLayers()
{
backgroundMask.lineWidth=线宽
backgroundMask.fillColor=nil
backgroundMask.strokeColor=UIColor.blue.cgColor
layer.mask=背景mask
layer.addSublayer(背景遮罩)
}
func createAnimation()
{
让动画=动画化(关键路径:“strokeEnd”)
animation.fromValue=0
动画。持续时间=1
animation.repeatCount=.infinity
backgroundMask.add(动画,forKey:“MyAnimation”)
}
重写函数绘图(rect:CGRect){
让边=6
设rect=self.bounds
let path=UIBezierPath()
让转弯半径:CGFloat=10
让旋转偏移=CGFloat(.pi/2.0)
设θ:CGFloat=CGFloat(2.0*.pi)/CGFloat(边)//在每个拐角处转弯多少
设width=min(rect.size.width,rect.size.height)//正方形的宽度
设中心=CGPoint(x:rect.origin.x+width/2.0,y:rect.origin.y+width/2.0)
//包围多边形的圆的半径
//请注意,半径是为角点调整的,这样最大的外部
//结果形状的尺寸始终正好是宽度-线宽
设半径=(宽度-线宽+拐角半径-(cos(θ)*拐角半径))/2.0
//从一个点开始绘图,默认情况下,该点位于右侧边缘
//但是可以抵消
变量角度=CGFloat(旋转偏移)
设角点=CGPoint(x:center.x+(半径-角点半径)*cos(角度),y:center.y+(半径-角点半径)*sin(角度))
移动路径(到:CGPoint(x:corner.x+cornerRadius*cos(角度+θ),y:corner.y+cornerRadius*sin(角度+θ)))

对于uu0..要在蓝色动画路径下添加灰色六边形,可以添加另一个
CAShapeLayer

var grayLayer = CAShapeLayer()
以类似于
backgroundMask
的方式进行设置:

grayLayer.lineWidth = lineWidth
grayLayer.fillColor = nil
grayLayer.strokeColor = UIColor.gray.cgColor
backgroundMask.path = path.cgPath
grayLayer.path = path.cgPath
将其路径设置为与
backgroundMask
相同的路径:

grayLayer.lineWidth = lineWidth
grayLayer.fillColor = nil
grayLayer.strokeColor = UIColor.gray.cgColor
backgroundMask.path = path.cgPath
grayLayer.path = path.cgPath
最后,在添加
backgroundMask
之前添加灰色层。这将使其位于底部:

layer.addSublayer(grayLayer)
layer.addSublayer(backgroundMask)
还请注意,路径绘制代码不需要进入
draw
。它可以进入
init

以下是动画的一帧的外观:


你能详细说明一下“看起来不像进度指标”吗?你还想要什么?@Sweeper编辑了这个问题。啊,我明白了。要做到这一点,你应该添加另一个
CAShapeLayer
。我试着添加一个CAGradientLayer来替换蓝色背景遮罩。这里是示例代码。gradientLayer.mask=backgroundMask gradientLayer.locations=[0.35,0.5,0.65]gradientLayer.frame=rect gradientLayer.colors=[UIColor.yellow.cgColor,UIColor.red.cgColor,UIColor.blue.cgColor]如果你不从视图的<代码>层>代码>中添加“代码>后台掩码< /代码>,那么它应该工作。如果它仍然不起作用,请考虑提出一个新问题,并提供一个。