How can I change the color of an element using a UIBezierPath?

一笑奈何 提交于 2019-12-23 12:58:04

问题


First post on stackoverflow so, first and foremost, hello!

I'm trying my hand at Swift for the first time and am working a project and just needed some help on a problem I'm having. I've got a circle using a UIBezierPath that I'd like to change the color of, dynamically. However, when I try to even "hard code" the color, I'm unable to get it to change. I've tried looking here: How to change the color of a UIBezierPath in Swift?, but it didn't answer my question. However, I do see that one answer there does state that a Bezier path has no color. If so, how would I then go about altering the color of the circle going along its path?

Here's the code I'm working with:

    outerCircle.path = UIBezierPath(ovalInRect: CGRect(x: 0.0, y: 0.0, width: frameSize.width, height: frameSize.height)).CGPath
    outerCircle.lineWidth = 8.0
    outerCircle.strokeStart = 0.0
    outerCircle.strokeEnd = 0.45
    outerCircle.lineCap = kCALineCapRound
    outerCircle.fillColor = UIColor.clearColor().CGColor
    outerCircle.strokeColor = UIColor.grayColor().CGColor
    outerCircleView.layer.addSublayer(outerCircle)

    outerCircle.strokeStart = 0.0
    outerCircle.strokeEnd = 1.0

    vibrancyView.contentView.addSubview(outerCircleView)

    innerCircleView.frame.size = frameSize

    let innerCirclePadding: CGFloat = 12
    innerCircle.path = UIBezierPath(ovalInRect: CGRect(x: innerCirclePadding, y: innerCirclePadding, width: frameSize.width - 2*innerCirclePadding, height: frameSize.height - 2*innerCirclePadding)).CGPath
    innerCircle.lineWidth = 4.0
    innerCircle.strokeStart = 0.5
    innerCircle.strokeEnd = 0.9
    innerCircle.lineCap = kCALineCapRound
    innerCircle.fillColor = UIColor.clearColor().CGColor
    innerCircle.strokeColor = UIColor.grayColor().CGColor
    innerCircleView.layer.addSublayer(innerCircle)

Again, I apologize if this is an obvious answer or has already been answered. I appreciate any advice that would help point me in the right direction. Thank you.

UPDATE: So here's what I tried doing. I changed the fill and stroke colors of both inner and outer circles to green, but I still have clear circles:

        outerCircle.path = UIBezierPath(ovalInRect: CGRect(x: 0.0, y: 0.0, width: frameSize.width, height: frameSize.height)).CGPath
    outerCircle.lineWidth = 8.0
    outerCircle.strokeStart = 0.0
    outerCircle.strokeEnd = 0.45
    outerCircle.lineCap = kCALineCapRound
    outerCircle.fillColor = UIColor.greenColor().CGColor
    outerCircle.strokeColor = UIColor.greenColor().CGColor
    outerCircleView.layer.addSublayer(outerCircle)

    outerCircle.strokeStart = 0.0
    outerCircle.strokeEnd = 1.0

    vibrancyView.contentView.addSubview(outerCircleView)

    innerCircleView.frame.size = frameSize

    let innerCirclePadding: CGFloat = 12
    innerCircle.path = UIBezierPath(ovalInRect: CGRect(x: innerCirclePadding, y: innerCirclePadding, width: frameSize.width - 2*innerCirclePadding, height: frameSize.height - 2*innerCirclePadding)).CGPath
    innerCircle.lineWidth = 4.0
    innerCircle.strokeStart = 0.5
    innerCircle.strokeEnd = 0.9
    innerCircle.lineCap = kCALineCapRound
    innerCircle.fillColor = UIColor.greenColor().CGColor
    innerCircle.strokeColor = UIColor.greenColor().CGColor
    innerCircleView.layer.addSublayer(innerCircle)

I'd like to have the circles change colors.


回答1:


A path has no color. It's a path! Only a graphics context has a stroke color / fill color. Sooner or later you will have a graphics context - a bezier path is useless without one. When you do, set its path to your bezier path, set its stroke / fill color as desired, and then stroke / fill the path. Voilà.

In your case, you seem to have a pair of CAShapeLayer objects. You can change their stroke / fill colors, because they have a graphics context - they take the path and colors you give them, and draw them for you by filling and stroking the path. Fine. But you cannot change a bezier path's stroke or fill color - it's just a path. The entire notion is meaningless.

Having said all that, it is far from clear what issue you are having. Based on your code, I ran this bit of it:

class ViewController: UIViewController {
    @IBOutlet weak var outerCircleView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let outerCircle = CAShapeLayer()
        let frameSize = outerCircleView.frame.size
        outerCircle.path = UIBezierPath(ovalInRect: CGRect(x: 0.0, y: 0.0, width: frameSize.width, height: frameSize.height)).CGPath
        outerCircle.lineWidth = 8.0
        outerCircle.strokeStart = 0.0
        outerCircle.strokeEnd = 0.45
        outerCircle.lineCap = kCALineCapRound
        outerCircle.fillColor = UIColor.clearColor().CGColor
        outerCircle.strokeColor = UIColor.grayColor().CGColor
        outerCircleView.layer.addSublayer(outerCircle)

    }
}

It builds and runs, and I see exactly what I would expect to see: a thick gray part-circle:

That is because this shape layer has a clear fill color and a grey stroke color. If you don't like those colors, ask the shape layer to give you different colors.

UPDATE You updated your code to show a second version involving green fill and stroke. So I tried your second code:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let outerCircle = CAShapeLayer()
    let frameSize = outerCircleView.frame.size
    outerCircle.path = UIBezierPath(ovalInRect: CGRect(x: 0.0, y: 0.0, width: frameSize.width, height: frameSize.height)).CGPath
    outerCircle.lineWidth = 8.0
    outerCircle.strokeStart = 0.0
    outerCircle.strokeEnd = 0.45
    outerCircle.lineCap = kCALineCapRound
    outerCircle.fillColor = UIColor.greenColor().CGColor
    outerCircle.strokeColor = UIColor.greenColor().CGColor
    outerCircleView.layer.addSublayer(outerCircle)

    outerCircle.strokeStart = 0.0
    outerCircle.strokeEnd = 1.0

}

And, as expected, I got a green circle (it isn't an exact circle, but that is just because my view is not a perfect square):

So again I don't see what the problem is supposed to be: your code does just what I would expect your code to do.



来源:https://stackoverflow.com/questions/29503627/how-can-i-change-the-color-of-an-element-using-a-uibezierpath

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!