首页 文章

带渐变的CAShapeLayer

提问于
浏览
1

我在向CAShapeLayer添加渐变时遇到问题 . 我创建了圆形图层,我想为它添加渐变 . 因此,我创建了一个CAGradientLayer并将其设置为图层边界并将其设置为图层,并且不会出现 . 我能做什么?

private func setupCircle() -> CAShapeLayer {
    let circlePath = UIBezierPath(arcCenter: CGPoint(x: progressView.frame.size.width / 2.0, y: progressView.frame.size.height / 2.0), radius: (progressView.frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(M_PI * 2.0), clockwise: true)

    let circleLayer = CAShapeLayer()
    circleLayer.path = circlePath.CGPath
    circleLayer.fillColor = nil
    circleLayer.strokeColor = UIColor.yellowColor().CGColor
    circleLayer.backgroundColor = UIColor.yellowColor().CGColor
    circleLayer.lineWidth = configurator.lineWidth
    circleLayer.strokeEnd = 1.0

    return circleLayer
}

private func setupGradient() -> CAGradientLayer {
    let gradient = CAGradientLayer()
    gradient.colors = [UIColor.clearColor().CGColor, UIColor.yellowColor().CGColor, UIColor.greenColor().CGColor]
    gradient.locations = [0.0, 0.25, 1.0]
    gradient.startPoint = CGPointMake(0, 0)
    gradient.endPoint = CGPointMake(1, 1)
    return gradient
}

let circle = setupCircle()
let gradient = setupGradient()

gradient.frame = circle.bounds
gradient.mask = circle

progressView.layer.addSublayer(circle)
progressView.layer.insertSublayer(gradient, atIndex: 0)

EDIT: 我已将setupCircle方法更改为:

private func setupCircle() -> CAShapeLayer {
    let circleLayer = CAShapeLayer()
    circleLayer.frame = progressView.bounds.insetBy(dx: 5, dy: 5)
    circleLayer.path = UIBezierPath(ovalInRect: CGRectMake(progressView.center.x, progressView.center.y, progressView.bounds.size.width, progressView.bounds.size.height)).CGPath
    circleLayer.fillColor = nil
    circleLayer.strokeColor = UIColor.yellowColor().CGColor
    circleLayer.backgroundColor = UIColor.yellowColor().CGColor
    circleLayer.lineWidth = configurator.lineWidth
    circleLayer.strokeEnd = 1.0

    return circleLayer
}

在这里效果,我做得对吗?:

EDIT 2: 我已将 circleLayer.path = UIBezierPath(ovalInRect: CGRectMake(progressView.center.x, progressView.center.y, progressView.bounds.size.width, progressView.bounds.size.height)).CGPath 更改为 circleLayer.path = UIBezierPath(ovalInRect: circleLayer.bounds).CGPath 并且它更好但仍然不是我想要的:

enter image description here

1 回答

  • 1

    您可以创建图层并将它们添加到 viewDidLoad 中的图层层次结构中,但是您不应该在那里执行任何框架逻辑,因为此时布局未更新 . 尝试将正在进行任何帧计算的所有代码移动到 viewDidLayoutSubviews .

    每次更新布局时也应该这样做,所以将它从 setupCircle 移到 viewDidLayoutSubviews

    let circlePath = UIBezierPath(...)
    circleLayer.path = circlePath.cgPath
    

    Edit:

    另外我看不出你在哪里设置 circleLayer 's frame? It'不足以设置它's path. If you have CGRect.zero rect for a mask, it will completely hide it'的父层 .

    我建议更换这个:

    let circlePath = UIBezierPath(arcCenter: CGPoint(x: progressView.frame.size.width / 2.0, y: progressView.frame.size.height / 2.0), radius: (progressView.frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(M_PI * 2.0), clockwise: true)
    

    有了这个:

    circleLayer.bounds = progressView.frame.insetBy(dx: 5, dy: 5)
    circleLayer.path = UIBezierPath(ovalIn: circleLayer.bounds).cgPath
    

    这样你'll have both frame and path set. Also be careful about coordinate system. I'我不确定视图层次结构中 progressView 的位置,也许你不是'll need it' s bounds .

    Edit 2: 你还应该删除几行代码 .

    • 这使您的圆形图层完全不透明,这使得形状本身不可见 .
    circleLayer.backgroundColor = UIColor.yellowColor().CGColor
    
    • 你不应该将它用作面具:
    progressView.layer.addSublayer(circle)
    

相关问题