Search code examples
iosios7

Round corner Gradient UIButton iOS


Hi I would like to create a button similar to (attached) image.

enter image description here

challenge here is round corner with gradient color. I was able to create round corner using

view.layer setCornerRadius:radius; view.layer setMasksToBounds:YES;

I am also able to create single border color

view.layer.borderColor = color.CGColor; view.layer.borderWidth = width;

But what need to be done for gradient border color?

I did following but it is not as desired. I followed this post but it does not provide me gradient border color. UIButton w/ gradient, rounded corners, border, and drop shadow

Can anyone help me understand, how can i draw gradient border for UIButton. Pseudo code/Example will be very helpful.


Solution

  • This applies a linear gradient to the line around a round rect by creating a polygon round rect with a hole cut in the middle and then using that to clip a fill of the linear gradient.

    class DisplayView : UIView {
        override func drawRect(var rect: CGRect) {
            let context = UIGraphicsGetCurrentContext()
    
            CGContextSaveGState(context)
    
            // Inset the rect so we can stroke it and not be outside the button bounds
            rect = CGRectInset(rect, 4.0, 4.0)
    
            // Construct the the bounds
            var path = CGPathCreateWithRoundedRect(rect, rect.size.height / 2, rect.size.height / 2, nil)
    
            // Fill the middle with white (or other background color
            CGContextAddPath(context, path)
            CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor)
            CGContextFillPath(context)
    
            // stroke the path
            path = CGPathCreateCopyByStrokingPath(path, nil, 4.0, kCGLineCapButt, kCGLineJoinBevel, 0)
    
            // Add the outer edge of the button frame
            CGContextAddPath(context, path)
    
            // Create a gradient from white to red
            let colors = [
                UIColor.yellowColor().CGColor,
                UIColor.redColor().CGColor
            ]
    
            // Set the round rect as the clip
            CGContextClip(context)
    
            // Fill the path with the radial gradient
            let baseSpace = CGColorSpaceCreateDeviceRGB();
            let gradient = CGGradientCreateWithColors(baseSpace, colors, nil);
    
            CGContextDrawLinearGradient(
                context,
                gradient,
                CGPoint(x:0, y:0),
                CGPoint(x:CGRectGetMaxX(rect), y:CGRectGetMaxY(rect)),
                .allZeros)
    
            // Fill the line
            CGContextFillPath(context)
    
            CGContextRestoreGState(context)
        }
    }
    

    Swift 4

    class DisplayView : UIView {
        override func draw(_ rect: CGRect) {
            var rect = rect
            let context = UIGraphicsGetCurrentContext()
    
            context!.saveGState()
    
            // Inset the rect so we can stroke it and not be outside the button bounds
            rect = rect.insetBy(dx: 4.0, dy: 4.0)
    
            // Construct the the bounds
            var path = CGPath(roundedRect: rect,
                              cornerWidth: rect.size.width / 2,
                              cornerHeight: rect.size.height / 2,
                              transform: nil)
    
            // Fill the middle with white (or other background color
            context!.addPath(path)
            context?.setFillColor(UIColor.clear.cgColor)
            context?.fillPath()
    
            // stroke the path
            path = path.copy(strokingWithWidth: 4.0,
                             lineCap: CGLineCap.butt,
                             lineJoin: CGLineJoin.bevel,
                             miterLimit: 0)
    
            // Add the outer edge of the button frame
            context?.addPath(path)
    
            // Create a gradient from white to red
            let colors = [
                UIColor.yellow.cgColor,
                UIColor.red.cgColor
            ]
    
            // Set the round rect as the clip
            context?.clip()
    
            // Fill the path with the radial gradient
            let baseSpace = CGColorSpaceCreateDeviceRGB();
            let gradient = CGGradient(colorsSpace: baseSpace,
                                      colors: colors as CFArray,
                                      locations: nil);
    
            context?.drawLinearGradient(gradient!,
                                        start: CGPoint(x:0, y:0),
                                        end: CGPoint(x: rect.maxX, y: rect.maxY),
                                        options: CGGradientDrawingOptions())
    
            // Fill the line
            context?.fillPath()
    
            context?.restoreGState()
        }
    }