0

How to add gradient to UIButton title, while the button background is clear, but corner boarder is gradient as well.

I found how to add gradient border here but have no clue how make gradient label. It would be great if label gradient would match border gradient color.

Maybe I can create this effect somehow with mask that is shaped like label?

Community
  • 1
  • 1
Xernox
  • 1,706
  • 1
  • 23
  • 37

4 Answers4

5

Hi the easies way is to create a UIColor from patternImage like so:

let image = UIImage(named: "gradient.jpeg");
let color = UIColor(patternImage: image!);

Then just use the color where you need:

buttonAction.layer.borderWidth = 1;
buttonAction.layer.cornerRadius = 5;
buttonAction.layer.borderColor = color.cgColor;

buttonAction.setTitleColor(color, for: .normal);

Result: enter image description here

for creating a gradient UIColor use this method: (you can add it to an UIColor extension)

func gradientColorFrom(color color1:UIColor, toColor color2:UIColor ,withSize size:CGSize) ->UIColor
{
  UIGraphicsBeginImageContextWithOptions(size, false, 0);
  let context = UIGraphicsGetCurrentContext();
  let colorspace = CGColorSpaceCreateDeviceRGB();

  let colors = [color1.cgColor, color2.cgColor] as CFArray;

  let gradient = CGGradient(colorsSpace: colorspace, colors: colors, locations: nil);
  context!.drawLinearGradient(gradient!, start: CGPoint(x:0, y:0), end: CGPoint(x:size.width, y:0), options: CGGradientDrawingOptions(rawValue: UInt32(0)));

  let image = UIGraphicsGetImageFromCurrentImageContext();

  UIGraphicsEndImageContext();

  let finalCColor = UIColor(patternImage: image!);
  return finalCColor;

}
  • for Horizontal gradient use CGPoint(x:size.width, y:0)
  • for Vertical gradient use CGPoint(x:0, y:size.height)
Constantin Saulenco
  • 2,353
  • 1
  • 22
  • 44
  • That is exactly what I am looking for. In this case if button width will remain the same and title will be "Some", I guess "S" will be red and "e" will be light blue? Is it possible to achieve that "S" would be violet and "e" dark blue? – Xernox Nov 16 '16 at 19:50
  • I just updated my answer try the `gradientColorFrom(color ,toColor, withSize)` method – Constantin Saulenco Nov 16 '16 at 21:11
  • While your example does work, buttons tittle color does not correspond to border color – Xernox Nov 17 '16 at 07:34
4

While Constantin answer does work, title label gradient will not necessarily match border color : enter image description here

So here's a my solution:

class GradientButton: UIButton {
    override func awakeFromNib() {

        layoutIfNeeded()

        let gradientBorder = CAGradientLayer()
        gradientBorder.frame =      bounds
        //Set gradient to be horizontal
        gradientBorder.startPoint = CGPoint(x: 0, y: 0.5)
        gradientBorder.endPoint =   CGPoint(x: 1, y: 0.5)
        gradientBorder.colors =    [UIColor.red.cgColor, UIColor.yellow.cgColor]

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

        layer.addSublayer(gradientBorder)

        let gradient =        CAGradientLayer()
        gradient.frame =      bounds
        //Set gradient to be horizontal
        gradient.startPoint = CGPoint(x: 0, y: 0.5)
        gradient.endPoint =   CGPoint(x: 1, y: 0.5)
        gradient.colors =     [UIColor.red.cgColor, UIColor.yellow.cgColor]

        layer.insertSublayer(gradient, at: 0)

        let overlayView = UIView(frame: bounds)
        overlayView.isUserInteractionEnabled = false
        overlayView.layer.insertSublayer(gradient, at: 0)
        overlayView.mask = titleLabel

        addSubview(overlayView)
    }
}

And the result:

enter image description here

Xernox
  • 1,706
  • 1
  • 23
  • 37
0

You can create gradient layer and add the same to UIButton

CAGradientLayer *gradient = [CAGradientLayer layer];
     gradient.frame = btn.bounds;
     gradient.colors = [NSArray arrayWithObjects:
                      (id)[[UIColor colorWithRed:255.0f/255.0f green:255.0f/255.0f blue:255.0f/255.0f alpha:.6f] CGColor],
                      (id)[[UIColor colorWithRed:200.0f/255.0f green:200.0f/255.0f blue:200.0f/255.0f alpha:.4f] CGColor],
                      (id)[[UIColor colorWithRed:150.0f/255.0f green:150.0f/255.0f blue:150.0f/255.0f alpha:.4f] CGColor],
                      (id)[[UIColor colorWithRed:100.0f/255.0f green:100.0f/255.0f blue:100.0f/255.0f alpha:.4f] CGColor],
                      (id)[[UIColor colorWithRed:50.0f/255.0f green:50.0f/255.0f blue:50.0f/255.0f alpha:.4f] CGColor],
                      (id)[[UIColor colorWithRed:5.0f/255.0f green:5.0f/255.0f blue:5.0f/255.0f alpha:.4f] CGColor],
                      nil];
    [btn.layer insertSublayer:gradient atIndex:0];

    CAGradientLayer *glossLayer = [CAGradientLayer layer];
    glossLayer.frame = btn.bounds;
    glossLayer.colors = [NSArray arrayWithObjects:
                     (id)[UIColor colorWithWhite:1.0f alpha:0.4f].CGColor,
                     (id)[UIColor colorWithWhite:1.0f alpha:0.1f].CGColor,
                     (id)[UIColor colorWithWhite:0.75f alpha:0.0f].CGColor,
                     (id)[UIColor colorWithWhite:1.0f alpha:0.1f].CGColor,
                     nil];
    glossLayer.locations = [NSArray arrayWithObjects:
                        [NSNumber numberWithFloat:0.0f],
                        [NSNumber numberWithFloat:0.5f],
                        [NSNumber numberWithFloat:0.5f],
                        [NSNumber numberWithFloat:1.0f],
                        nil];
     [btn.layer insertSublayer:glossLayer atIndex:0];

Hope it helps.

user2071152
  • 1,161
  • 1
  • 11
  • 25
  • Yeah, I am aware how to do that, but that is not what I am looking for because in your case button background color is not .clear, label color is not gradient and button does not have a border. And I am not sure why do you repeat almost the same gradient layer twice? – Xernox Nov 16 '16 at 20:03
0

swift 4 set gradient layer for Button and set title for button

let gradient = CAGradientLayer()
        gradient.frame = CGRect(x: 0, y: 0, width: buttonSchedule.frame.width, height: 34)
        gradient.colors = [
            UIColor(red:0.89, green:0.02, blue:0.07, alpha:1).cgColor,
            UIColor(red:0.93, green:0.43, blue:0.1, alpha:1).cgColor ]
        gradient.locations = [0, 1]
        gradient.startPoint = CGPoint.zero
        gradient.endPoint = CGPoint(x: 1.02, y: 1)
        gradient.cornerRadius = 17
        buttonSchedule.layer.insertSublayer(gradient, below: buttonSchedule.titleLabel?.layer)
buttonSchedule.setTitle("Schedule", for: .normal)
        buttonSchedule.contentEdgeInsets = UIEdgeInsets.init(top: 0, left: 20, bottom: 0, right: 0)
        buttonSchedule.contentHorizontalAlignment = .left
        buttonSchedule.setTitleColor(UIColor.white, for: .normal)
Srinivasan_iOS
  • 972
  • 10
  • 12