3/15/15

iOS Gradient View with Clipped Path

Custom gradient view with support for 3 shapes: default, circle, circle-outline.
Copy path with CGPathCreateCopyByStrokingPath, clip, then draw gradient.




//swift

import UIKit

class ViewController: UIViewController
{
    override func viewDidLoad()
    {
        super.viewDidLoad()

        var gv = [ESGradientView]()
        var x = 100
        for i in 0...5
        {
            var g = ESGradientView()
            g.frame = CGRect(x:x, y:200, width:100, height:100)
            g.gradientColors = i < 3 ? g.gradientColors : [UIColor.redColor().CGColor, UIColor.blackColor().CGColor]
            gv.append(g)
            self.view.addSubview(g)
            x += 110
        }

        gv[1].shape = .Circle
        gv[2].shape = .CircleOutline
        gv[4].shape = .Circle
        gv[5].shape = .CircleOutline
        gv[5].circleOutlineWidth = 1
    }
}


class ESGradientView: UIView
{

    enum Shape
    {
        case Default, Circle, CircleOutline
    }

    var shape = Shape.Default
    var circleOutlineWidth:Int = 4
    var gradientColors = [UIColor.redColor().CGColor, UIColor.blueColor().CGColor]
    var gradientLocations:[CGFloat] = [0, 1]
    var gradientEndOffset:CGFloat = 20


    override func drawRect(rect: CGRect)
    {
        var context = UIGraphicsGetCurrentContext()

        if (shape == .Circle)
        {
            let path = getCirclePath(1)
            path.addClip()
        }
        else if (shape == .CircleOutline)
        {
            let path = getCirclePath(circleOutlineWidth + 2)
            var pathRef = CGPathCreateCopyByStrokingPath(path.CGPath, nil, CGFloat(circleOutlineWidth), kCGLineCapRound, kCGLineJoinRound, 1)
            UIBezierPath(CGPath: pathRef).addClip()
        }

        var gradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), gradientColors, gradientLocations)
        let gradientEndPoint = CGPointMake(bounds.width - gradientEndOffset, bounds.height - gradientEndOffset)
        CGContextDrawLinearGradient(context, gradient!, CGPointZero, gradientEndPoint, UInt32(kCGGradientDrawsAfterEndLocation))
    }   

    func getCirclePath(inset:Int) -> UIBezierPath
    {
        let center = CGFloat(bounds.width * 0.5)
        let radius = CGFloat(center * CGFloat(100 - inset) * 0.01)
        let centerPoint = CGPointMake(center, center)
        var cp = UIBezierPath(arcCenter:centerPoint, radius:radius, startAngle:0, endAngle:CGFloat(M_PI * 2), clockwise:true)

        return cp
    }
}

5 comments:

  1. I am really loving the theme/design of your web site. Do you ever run into any browser compatibility problems? A few of my blog readers have complained about my website not working correctly in Explorer but looks great in Chrome. Do you have any tips to help fix this issue? mobile phone mockup

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Enjoyed looking at this, very good stuff, thanks . iphone mockups

    ReplyDelete
  4. I truly enjoy examining on this website , it has good content . ipad psd

    ReplyDelete
  5. My partner and i still can not quite assume that I could be one of those reading through the important recommendations found on this blog. My family and I are sincerely thankful for your generosity and for presenting me potential to pursue the chosen career path. Appreciate your sharing the important information I acquired from your web-site. android mockup psd

    ReplyDelete