1

I am have create some custom layer and added on UIView ,i have two CAShaper Layer but i am just showing only one example here

    hexBorderOtline = CAShapeLayer()
    hexBorderOtline.name = "dhiru_border_hidden"
    hexBorderOtline.path = path2.cgPath
    hexBorderOtline.lineCap = .round  
    hexBorderOtline.strokeColor = inActiveBorderColor.cgColor
    hexBorderOtline.fillColor = UIColor.clear.cgColor
    self.layer.addSublayer(hexBorderOtline)

I want to change it's border color when button is clicked.

func btnAction()
{
    hexBorderOtline.strokeColor = activeBorderColor.cgColor
}

But this is not working , i am posting one reference image what i need to do on button click .

enter image description here

Bhavik Modi
  • 1,517
  • 14
  • 29
Dhiru
  • 3,040
  • 3
  • 25
  • 69
  • how hexBorderOtline is defined? – Alastar May 31 '19 at 12:43
  • I have added the code , how i am initializing `var hexBorderOtline:CAShapeLayer!` ` – Dhiru May 31 '19 at 12:55
  • hexBorderOtline must a global var and change color in button with hexBorderOtline.strokeColor = UIColor.blue.cgColor on mainthread. I try just now and works, If doesnt work you lose the reference of object or works in new thread, be sure you are on mainthread. – Jose Pose S May 31 '19 at 13:02

3 Answers3

2

Your method of toggling the shape layer’s stroke color is correct:

enter image description here

All I’m doing is:

var enabled = false

@IBAction func didTapButton(_ sender: Any) {
    enabled = !enabled
    hexBorderOtline.strokeColor = enabled ? activeBorderColor.cgColor : inActiveBorderColor.cgColor
}

So, your problem rests elsewhere. For example:

  • Perhaps you have another shape layer that is on top of the one for which you’re changing color.

  • Or perhaps your ivar, is pointing to another shape layer.

  • Or perhaps your button isn’t hooked up to your btnAction routine (the absence of any @IBAction or @objc makes me suspect you’re not calling this routine).

It’s going to be something simple like that.

I’d suggest you add print(hexBorderOtline) where you create the CAShapeLayer and again in the btnAction and confirm that both:

  1. You are seeing both sets of print statements; and

  2. They are printing the same memory address associated with the shape layer (i.e. make sure they are they referring to the same shape layer).

But it’s got to be something like that. This is the correct way to change strokeColor and that will update the shape layer automatically for you. Your problem rests elsewhere.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • how are you creating shaper layer can you please post , i have create that btnAction different function which is called from actual Action button. – Dhiru Jun 01 '19 at 09:56
  • Are you masking that layer or adding as layer ? – Dhiru Jun 01 '19 at 09:57
  • I cut and paste your code, so it is exactly as it was in your question (that’s why I’m using that `hexBorderOtline` name; lol). I made the line thicker so you could see it more clearly, but it works the same without that. There’s absolutely nothing special here. Add shape layer as sublayer, set its path, and then when you change its `strokeColor`, the shape layer changes color. It’s as simple as that. Create blank project and try it. It works fine. There’s got to be something else going on not included your question. Did you do the diagnostics that I outlined in my answer? – Rob Jun 01 '19 at 12:28
1

Try this:

func btnAction()
{
    hexBorderOtline.removeFromSuperlayer()
    hexBorderOtline.strokeColor = activeBorderColor.cgColor
    self.layer.addSublayer(hexBorderOtline)
}

Without UIView:

class ViewController: UIViewController {

    var hexBorderOtline: CAShapeLayer!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        hexBorderOtline = CAShapeLayer()
        hexBorderOtline.name = "dhiru_border_hidden"
        hexBorderOtline.path = UIBezierPath(arcCenter: CGPoint(x:self.view.frame.size.width/2, y: self.view.frame.size.height/2), radius: self.view.frame.size.height/2, startAngle: 180, endAngle: 0.0, clockwise: true).cgPath
        hexBorderOtline.lineCap = .round
        hexBorderOtline.strokeColor = UIColor.gray.cgColor
        hexBorderOtline.fillColor = UIColor.clear.cgColor
        self.view.layer.addSublayer(hexBorderOtline)
    }

    @IBAction func updateColor(_ sender: Any) {
        hexBorderOtline.removeFromSuperlayer()
        hexBorderOtline.strokeColor = UIColor.red.cgColor
        self.view.layer.addSublayer(hexBorderOtline)
    }
}
Bhadresh Kathiriya
  • 3,147
  • 2
  • 21
  • 41
0

If you are having only 2 layers which shows active and inactive modes with colours you can create two separate layers with different stroke colour and add them as a sublayers into the main layer. The default layer colour which you want to show should be added afterwards. When the button is clicked then you need to only hide/show the sublayers and you will be good to go.

Hope this helps.

BhargavR
  • 1,095
  • 7
  • 14