1

I am trying to create a button with a gradient color, but I can't seem to make it work. No color is applied to the borderColor property of my button. I tried implementing the code suggested by another SO post, but it does not work. Not sure why. Can someone help me understand why?

The code that I am using to change the layout of my button is:

// Constraints
myButton.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
myButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50).isActive = true
myButton.heightAnchor.constraint(equalToConstant: myButton.height).isActive = true
myButton.widthAnchor.constraint(equalToConstant: myButton.width).isActive = true

// Layout
myButton.backgroundColor = UIColor.black
myButton.tintColor = UIColor.white
myButton.layer.cornerRadius = callButtonHeightAndWidth.height / 2
myButton.layer.borderWidth = 10
myButton.setTitle("Test", for: .normal)
myButton.titleLabel?.font = UIFont(name: "HelveticaNeue-Regular", size: 27)

I tried to extend UIView with a function I call setGradientBorderWidthColor and the code looks like:

func setGradientBorderWidthColor(button: UIButton)
    {
        let gradientColor = CAGradientLayer()
        gradientColor.frame =  CGRect(origin: CGPoint.zero, size: button.frame.size)
        gradientColor.colors = [UIColor.red.cgColor, UIColor.blue.cgColor, UIColor.green.cgColor]

        let shape = CAShapeLayer()
        shape.lineWidth = 3
        shape.path = UIBezierPath(rect: button.bounds).cgPath
        shape.strokeColor = UIColor.black.cgColor
        shape.fillColor = UIColor.clear.cgColor
        gradientColor.mask = shape

        button.layer.addSublayer(gradientColor)
    }

I also tried to just place the same code above in the viewDidLoadfunction in my ViewController, but that did not work either. Any suggestions?

Edit 1:

enter image description here

Playing with the code and the suggestions provided I ended up with this. The issue is that whenever I add a corner radius to the button, the edges are cut off.

decipher
  • 137
  • 6
  • 14

2 Answers2

0

just remove two line from your code then your code will be working fine for you.

myButton.layer.borderWidth = 10
myButton.layer.cornerRadius = 10

code will be look like this :

 myButton.backgroundColor = UIColor.clear
            myButton.frame = CGRect(x: 100, y: 100, width: 150, height: 40)
            myButton.tintColor = UIColor.black
            myButton.setTitle("Test", for: .normal)
            myButton.titleLabel?.font = UIFont(name: "HelveticaNeue- 
        Regular", size: 27)
            setGradientBorderWidthColor(button: myButton)
            self.view.addSubview(myButton)

Replace Your setGradientBorderWidthColor function With This function

func setGradientBorderWidthColor(button: UIButton)
    {
        let gradientColor = CAGradientLayer()
        gradientColor.frame =  CGRect(origin: CGPoint.zero, size: button.frame.size)
        gradientColor.colors = [UIColor.blue.cgColor, UIColor.green.cgColor]

        let pathWithRadius = UIBezierPath(roundedRect:button.bounds, byRoundingCorners:[.topRight, .topLeft, .bottomLeft , .bottomRight], cornerRadii: CGSize(width: 20.0, height: 20.0))
        let shape = CAShapeLayer()
        shape.lineWidth = 3
        shape.path = pathWithRadius.cgPath
        shape.strokeColor = UIColor.black.cgColor
        shape.fillColor = UIColor.clear.cgColor
        gradientColor.mask = shape
        button.layer.mask = shape
        button.layer.addSublayer(gradientColor)
    }

OutPut:

GradientBorderWidthColor

nishee
  • 141
  • 7
  • Alright, so this works partially. If I add a corner radius, the eges will cut off. I have edited my post to include an image of this. – decipher Apr 17 '18 at 11:50
  • @Araine, Now check edit answer, hope now this work for you.! – nishee Apr 17 '18 at 12:45
  • @Araine, If it's help you approved the answer. – nishee Apr 18 '18 at 06:40
  • Hi @nishee, and thank you for your help! I have issues with the corners in terms of how they are rendered. If you want to make a circular button, the 0, 90, 180, and 270 degrees of the circle are cut off. I am not sure why. – decipher Apr 18 '18 at 09:49
  • @Araine, you want make circular button.? if yes can you tell me x y and hight width of your button – nishee Apr 18 '18 at 10:11
0

You can make a gradient border by following the below code:

func makeButton(){

    let buttonView = UIButton()
    self.view.addSubview(buttonView)
    buttonView.translatesAutoresizingMaskIntoConstraints = false
    buttonView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: self.view.safeAreaInsets.top + 30).isActive = true
    buttonView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 40).isActive = true
    buttonView.widthAnchor.constraint(equalToConstant: 120
        ).isActive = true
    buttonView.heightAnchor.constraint(equalToConstant: 50).isActive = true
    self.view.layoutIfNeeded()


    let outerPath = UIBezierPath()
    outerPath.move(to: CGPoint.init(x: buttonView.bounds.minX - 5, y: buttonView.bounds.minY - 5))
    outerPath.addLine(to: CGPoint.init(x: buttonView.bounds.maxX + 5, y: buttonView.bounds.minY - 5))
    outerPath.addLine(to: CGPoint.init(x: buttonView.bounds.maxX + 5, y: buttonView.bounds.maxY + 5))
    outerPath.addLine(to: CGPoint.init(x: buttonView.bounds.minX - 5, y: buttonView.bounds.maxY + 5))
    outerPath.close()

    let path = UIBezierPath()
    path.move(to: CGPoint.init(x: buttonView.bounds.minX + 5, y: buttonView.bounds.minY + 5))
    path.addLine(to: CGPoint.init(x: buttonView.bounds.maxX, y: buttonView.bounds.minY + 5))
    path.addLine(to: CGPoint.init(x: buttonView.bounds.maxX, y: buttonView.bounds.maxY))
    path.addLine(to: CGPoint.init(x: buttonView.bounds.minX + 5, y: buttonView.bounds.maxY))
    path.close()

    outerPath.append(path)

    let maskLayer = CAShapeLayer()
    maskLayer.fillRule = kCAFillRuleEvenOdd
    maskLayer.path = outerPath.cgPath
    maskLayer.fillColor = UIColor.red.cgColor
    buttonView.layer.addSublayer(maskLayer)

    self.view.layoutIfNeeded()

    let gradient = CAGradientLayer()
    gradient.frame = self.view.frame
    gradient.colors = [UIColor.blue.cgColor,
                       UIColor.red.cgColor]
    gradient.startPoint = CGPoint(x: 0, y: 1)
    gradient.endPoint = CGPoint(x: 1, y: 0)
    gradient.mask = maskLayer
    buttonView.layer.addSublayer(gradient)
    buttonView.setTitle("Hello World", for: .normal)
}

Basically, you have to make a a shapeLayer, make two paths and set the fillRule as kcaFillModeEvenOdd, apply a gradient to this mask. And there you have it:

enter image description here

SWAT
  • 1,107
  • 8
  • 19
  • Hi, @SWAT! Thank you for your response. How would you make rounded corners and even a circular button using your example? – decipher Apr 18 '18 at 09:50