set my gradient to an arc of BezierPath [duplicate] - ios

This question already has answers here:
How to draw a circle path with color gradient stroke
(4 answers)
Closed 5 years ago.
I've read some topics about but can't apply to me... I try to apply a gradient color to an arc drawed with a UIBezierPath.
The problem is that my gradient fill all the circle and not just the ring.
func layerWith(size: CGSize, color: UIColor) -> CALayer {
let layer: CAShapeLayer = CAShapeLayer()
var path: UIBezierPath = UIBezierPath()
let lineWidth: CGFloat = 2
layer.backgroundColor = nil
layer.path = path.cgPath
layer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
switch self {
case .ring:
path.addArc(withCenter: CGPoint(x: size.width / 2, y: size.height / 2),
radius: size.width / 2,
startAngle: 0,
endAngle: CGFloat(2 * M_PI),
clockwise: false);
layer.fillColor = UIColor.clear.cgColor
layer.strokeColor = color.cgColor
layer.lineWidth = lineWidth
let colorGradStart = UIColor(red: 0/255, green: 209/255, blue: 192/255, alpha: 1.0)
let colorGradEnd = UIColor(red: 00/255, green: 99/255, blue: 91/255, alpha: 1.0)
let gradient = CAGradientLayer()
gradient.frame = path.bounds
gradient.colors = [colorGradStart.cgColor, colorGradEnd.cgColor]
let shapeMask = CAShapeLayer()
shapeMask.path = path.cgPath
gradient.mask = shapeMask
layer.addSublayer(gradient)
}
return layer
}
So this code, apply the gradient to all the filled form, me i just need the arc.

One way to do it is to apply your CAShapeLayer to your gradient layer as a mask. Then it reveals the gradient.

You should set shapeMask's fillColor and strokeColor, not the layer.

Related

Positioning of CAShapeLayer

I'm currently trying to implement a CAShapeLayer. It works fine, but its position isn't working the way I want it to.
I want the circle to be displayed inside of the top selected UIView you see in the second image below. To do that, I tried to set arcCenter to circleView.center. But what's being displayed is the image below.
How it's being displayed:
I want it to be displayed in the center inside of this UIView:
My code:
func displayCircle() {
let color = UIColor(red: 11/255, green: 95/255, blue: 244/255, alpha: 1)
let trackLayer = CAShapeLayer()
let center = circleView.center
let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = UIColor.groupTableViewBackground.cgColor
trackLayer.lineWidth = 20
trackLayer.fillColor = UIColor.clear.cgColor
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeColor = color.cgColor
shapeLayer.lineWidth = 20
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineCap = CAShapeLayerLineCap.round
shapeLayer.strokeEnd = 0
circleView.layer.addSublayer(trackLayer)
circleView.layer.addSublayer(shapeLayer)
}
Edit, UIView's constraints:
You can simply change your center position of circle view like below,
let center = CGPoint(x: circleView.frame.size.width/2, y: circleView.frame.size.height/2)
Hope this way may help you.

UIButton with gradient border and rounded corners

What I am trying to get is the a custom UIButton that has a gradient border (just the border is gradient) and rounded corners. I almost got to where I wanted to be, but having issues with the corners.
Here is what I currently have:
Here is my code:
override func viewDidLoad() {
super.viewDidLoad()
let gradient = CAGradientLayer()
gradient.frame = CGRect(origin: CGPoint.zero, size: self.myButton.frame.size)
gradient.colors = [UIColor.blue.cgColor, UIColor.green.cgColor]
gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
gradient.cornerRadius = 15
let shape = CAShapeLayer()
shape.lineWidth = 5
shape.path = UIBezierPath(rect: self.myButton.bounds).cgPath
shape.strokeColor = UIColor.black.cgColor
shape.fillColor = UIColor.clear.cgColor
shape.cornerRadius = 15
gradient.mask = shape
self.myButton.clipsToBounds = true
self.myButton.layer.cornerRadius = 15
self.myButton.layer.addSublayer(gradient)
}
So the question is how do I display corners with gradient?
The problem is with the mask, try to remove shape.cornerRadius = 15 and change this:
shape.path = UIBezierPath(rect: self.myButton.bounds).cgPath
to this:
shape.path = UIBezierPath(roundedRect: self.myButton.bounds.insetBy(dx: 2.5, dy: 2.5), cornerRadius: 15.0).cgPath
Play with the values of the insets and cornerRadius to achieve your desired result.

Round left border of a UIButton

To round the bottom left corner of a UIButton, I took code from this answer and modified the line: borderLayer.strokeColor = GenerateShape.UIColorFromHex(0x989898, alpha: (1.0-0.3)).CGColor b/c it didn't work.
However, the left border of the UIButton is not rounded. How to fix?
Code
button.frame = CGRect(x: 0, y: 0, width: 0.5*popUpView.frame.width, height: 0.25*popUpView.frame.height)
button.layer.borderWidth = 3
button.roundBtnCorners(roundedCorners, radius: cornerRadius)
extension UIButton{
// Round specified corners of button
func roundBtnCorners(_ corners:UIRectCorner, radius: CGFloat)
{
let borderLayer = CAShapeLayer()
borderLayer.frame = self.layer.bounds
borderLayer.strokeColor = UIColor(red: 168/266, green: 20/255, blue: 20/255, alpha: 0.7).cgColor
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.lineWidth = 1.0
let path = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
borderLayer.path = path.cgPath
self.layer.addSublayer(borderLayer);
}
}
Istead of:
self.layer.addSublayer(borderLayer)
Try:
self.layer.mask = borderLayer
I cannot see how you are creating the parameters for roundBtnCorners but below is the line I changed in your code and it worked. I would check to make sure you are passing the correct parameters.
button.roundBtnCorners(.bottomLeft , radius: 10)
Solved it! It was because my button.layer.borderWidth = 3 was drawing a really thick rectangle, so I couldn't see the border drawn by roundBtnCorners
I deleted the line below:
button.layer.borderWidth = 3
Result:

How to set gradient color to UIImageView border

How to apply gradient color to UIImageView border color. What i tried is
let gradient: CAGradientLayer = CAGradientLayer()
let color0 = UIColor(red:0.0/255, green:0.0/255, blue:0.0/255, alpha:0.0).CGColor
let color1 = UIColor(red:0.0/255, green:0.0/255, blue: 0.0/255, alpha:0.71).CGColor
gradient.colors = [color0, color1]
gradient.locations = [0.0 , 1.0]
gradient.frame = CGRect(x: 0.0, y: 80.0, width: self.imgProfile.frame.size.width, height: self.imgProfile.frame.size.height-35)
self.imgProfile.layer.insertSublayer(gradient, atIndex: 0)
This is what required
Please guide, thanks
Update:
Tried this way
let gradient = CAGradientLayer()
gradient.frame = CGRect(origin: CGPointZero, size: self.imgPeopleProfile.frame.size)
gradient.colors = [UIColor.blueColor().CGColor, UIColor.greenColor().CGColor]
let shape = CAShapeLayer()
shape.lineWidth = 2
shape.path = UIBezierPath(rect: self.imgPeopleProfile.bounds).CGPath
shape.strokeColor = UIColor.blackColor().CGColor
shape.fillColor = UIColor.clearColor().CGColor
gradient.mask = shape
imgPeopleProfile.layer.cornerRadius = imgPeopleProfile.frame.size.width / 2
imgPeopleProfile.clipsToBounds = true
self.imgPeopleProfile.layer.addSublayer(gradient)
It gives
Please take Imageview Size Equal width and height ex. Width=100 and Height = 100 So it will show proper Circle. If you want to change the Size then please amke also change in the below Line .
shape.path = UIBezierPath(arcCenter: CGPoint(x: 50, y: 50), radius: CGFloat(50), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true).CGPath
With the radius of the Circle in above example its 50.
let gradient = CAGradientLayer()
gradient.frame = CGRect(origin: CGPointZero, size: self.imageView.frame.size)
gradient.colors = [UIColor(red:87.0/255, green:206.0/255, blue: 172.0/255, alpha:0.71).CGColor,UIColor(red:44.0/255, green:192.0/255, blue:208.0/255, alpha:1.0).CGColor]
imageView.layer.cornerRadius = imageView.frame.size.width / 2
imageView.clipsToBounds = true
let shape = CAShapeLayer()
shape.lineWidth = 5
shape.path = UIBezierPath(arcCenter: CGPoint(x: 50, y: 50), radius: CGFloat(50), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true).CGPath
shape.strokeColor = UIColor.blackColor().CGColor
shape.fillColor = UIColor.clearColor().CGColor
gradient.mask = shape
self.imageView.layer.addSublayer(gradient)

How to add gradient color to a CAShapeLayer created using UIBezierPath

I have tried this and this but still no success. Basically I want to create something like this (inner circle). Circle will be created according to some data lets say if data is 50 we will get a half circle and if its 100 we will get full circle.
And this is what I have so far, so how can I create the above design
I have created a View using interface builder, and drawn these circle using this code
override func viewDidLoad() {
let circlePath = UIBezierPath(arcCenter: CGPoint(x: myView.layer.frame.height/2,y: myView.layer.frame.height/2), radius: CGFloat(100), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.CGPath
shapeLayer.fillColor = UIColor.clearColor().CGColor
shapeLayer.strokeColor = UIColor.grayColor().CGColor
shapeLayer.lineWidth = 3.0
let colorCirclePath = UIBezierPath(arcCenter: CGPoint(x: myView.layer.frame.height/2,y: myView.layer.frame.height/2), radius: CGFloat(100), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)
let coloredShapeLayer = CAShapeLayer()
coloredShapeLayer.path = colorCirclePath.CGPath
coloredShapeLayer.fillColor = UIColor.clearColor().CGColor
coloredShapeLayer.strokeColor = UIColor.whiteColor().CGColor
coloredShapeLayer.lineWidth = 10.0
self.myView.layer.addSublayer(coloredShapeLayer)
self.myView.layer.addSublayer(shapeLayer)
}
This is how I am creating the gradient.
let gradient: CAGradientLayer = CAGradientLayer()
let startingColorOfGradient = UIColor(colorLiteralRed: 50/255, green: 189/255, blue: 170/255, alpha: 1.0).CGColor
let endingColorOFGradient = UIColor(colorLiteralRed: 133/255, green: 210/255, blue: 230/255, alpha: 1.0).CGColor
gradient.startPoint = CGPoint(x: 1.0, y: 0.5)
gradient.endPoint = CGPoint(x: 0.0, y: 0.5)
gradient.colors = [startingColorOfGradient , endingColorOFGradient]
self.myView.layer.insertSublayer(gradient, atIndex:0)
If you want a real simulation of gradient color you can check this SO answer .It's based on a cross that divided your rectangular view in 4 portions, then shift the colors on each portion to obtain a regular gradient applied to the layer mask.

Resources