My need is to show 3-colored distribution in a view. So I'm using following code.
func drawWithGradientLayer() {
// total contains sum of all values contained in segmentValues variable.
// I'm using green -> Orange -> Red colors as colors
if total == 0 {
return
}
if gradientLayer.superlayer != nil {
gradientLayer.removeFromSuperlayer()
}
var previous: CGFloat = (CGFloat(segmentValues[0])/CGFloat(total))
var locations: [NSNumber] = [previous]
for var i=1; i<segmentValues.count; i++ {
previous = previous + (CGFloat(segmentValues[i])/CGFloat(total))
locations.append(previous)
}
locations.append(1.0) // Line may need to be commented
gradientLayer = CAGradientLayer()
gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)
gradientLayer.startPoint = CGPointMake(0.0, 0.5);
gradientLayer.endPoint = CGPointMake(1.0, 0.5);
gradientLayer.colors = colors
gradientLayer.locations = locations
self.layer.insertSublayer(gradientLayer, atIndex: 0)
}
But problem is that gradient colors are not distributed according to my requirements. E.g if ihave values of [1,0,1] so bar should display 50% red & 0% orange and 50% red. If values are [0,0,1] then only redColor should be drawn. How can I achieve this without grid lines?
any other better solution will always be appreciated :)
The key here is to understand how locations
in CAGradientLayer work:
The gradient stops are specified as values between 0 and 1. The values must be monotonically increasing.
So you cannot specify locations like [1, 0, 1]
, but should rather use something like [0.0, 0.33, 0.67, 1.0]
, and the number of location values must be the same as your colors
count.
To make a gradient with short color transitions like in your images, you have to repeat each color twice and specify the appropriate locations:
So your code should be something like:
gradientLayer.colors = [
UIColor.greenColor().CGColor, UIColor.greenColor().CGColor,
UIColor.orangeColor().CGColor, UIColor.orangeColor().CGColor,
UIColor.redColor().CGColor, UIColor.redColor().CGColor
]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
gradientLayer.locations = [0.0, 0.2, 0.3, 0.7, 0.8, 1.0]
If you want to get a 2-color gradient while not changing its colors, you can set a value less than 0 for startPoint.x
or greater than 1 for endPoint.x
, and set multiple locations to zero, e.g.:
gradientLayer.startPoint = CGPoint(x: -0.01, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
gradientLayer.locations = [0.0, 0.0, 0.0, 0.0, 0.1, 1.0]
which would give a result similar to this:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With