Add gradient layer to uiviewcontroller uiview - ios

I am trying to create a simple gradient for the background of a UIViewController. My code is:
let gradientLayer = CAGradientLayer()
gradientLayer.frame = view.bounds
let bottomColor = UIColor(hue: 208 / 360, saturation: 82 / 100, brightness: 0.9, alpha: 1)
let topColor = UIColor(hue: 208 / 360, saturation: 41 / 100, brightness: 0.9, alpha: 1)
gradientLayer.colors = [bottomColor, topColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.1)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
view.layer.addSublayer(gradientLayer)
The gradient does not show. When I look in the view debugger, I do not see it. I check the frame of the view and it looks ok
x: 0, y:0, width: 375, height: 667
I've tried the view.layer.insert at method as well, but that did not work. If I do
view.layer.backgroundColor.orange
then I do see an orange background. Am I missing something?

Change
gradientLayer.colors = [bottomColor, topColor]
to
gradientLayer.colors = [bottomColor.cgColor, topColor.cgColor]

Related

Fill a CAShapeLayer with Gradient in swift?

I have filled the circle boundary with CAShapeLayer.Now i am giving my CAShape color as red but i want to give it as a gradient color.Please tell me how can i do this?
circlePath = UIBezierPath(arcCenter: centerPoint, radius: circleRadius, startAngle: CGFloat(1.5 * M_PI), endAngle: CGFloat(-0.5 * M_PI), clockwise: false)
//add gradient to the below
progressCircle = CAShapeLayer ()
progressCircle.path = circlePath?.cgPath
progressCircle.strokeColor = UIColor.red.cgColor
progressCircle.fillColor = UIColor.clear.cgColor
progressCircle.lineWidth = 4.0
progressCircle.strokeStart = 0
progressCircle.strokeEnd = 0.7
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]
circle.layer.addSublayer(progressCircle)
circle.layer.addSublayer(gradient)
I think you're missing the gradient frame, the gradient locations and you should add it to the layer's mask. The following example works for me:
let gradient = CAGradientLayer()
gradient.startPoint = CGPoint(x: 1, y: 0.5)
gradient.endPoint = CGPoint(x: 0, y: 0.5)
gradient.frame = CGRect(x: 0, y: 0, width: yourWidth, height: yourHeight)
gradient.colors = [
UIColor(white: 1, alpha: 0.1).cgColor,
UIColor(white: 1, alpha: 0.5).cgColor,
UIColor(white: 1, alpha: 0.9).cgColor
]
gradient.locations = [
0.0,
0.5,
1.0
]
circle.layer.mask = gradient
Hope this helps!

CAGradientLayer not changing the background color

I want to create a gradient as a background color for my UIView. I wrote this code
gradient.colors = [UIColor.blue,UIColor.yellow]
gradient.locations = [0.0 , 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
gradient.frame = CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height)
self.view.layer.insertSublayer(gradient, at: 0)
but the view still the same set on the Interface Builde. If I add this line before the code
self.view.backgroundColor = UIColor.clear
the background color changes to white
let gradient: CAGradientLayer = CAGradientLayer()
gradient.colors = [UIColor.blue.cgColor, UIColor.yellow.cgColor]
gradient.locations = [0.0 , 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
gradient.frame = CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height)
self.view.layer.insertSublayer(gradient, at: 0)
try this code. It works for me swift 3

UIVisualEffectView with CAGradientLayer not working on iOS 10

I'm trying to create an effect whereby a photo is blurry at the top, but not at the bottom, and the blurriness 'fades off' gradually. I achieved this with the code below, which worked fine in iOS9, but does not in iOS10.
I'm aware of a known bug, as described in this question, that prevents a layer having a mask and a blur on the same layer.
The difference between my question and the one linked, is I'm not interested in using a CAShapeLayer as my mask, but rather a CAGradientLayer. I've tried fiddling with adding views/masks/layers in different orders, but am not having much luck.
var visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
visualEffectView.frame = CGRect(x: 0.0, y:0.0, width: photo.bounds.width, height: photo.bounds.height)
photo.addSubview(visualEffectView)
let maskStartColour = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
let maskEndColour = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
let gradient = CAGradientLayer()
gradient.frame = CGRect(x: 0, y: 0, width: visualEffectView.bounds.width, height: visualEffectView.bounds.height)
let colors: [AnyObject] = [maskStartColour.cgColor, maskEndColour.cgColor]
gradient.colors = colors
gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient.endPoint = CGPoint(x: 0.0, y: 1.0)
visualEffectView.layer.mask = gradient

Gradiant in playground different from simulator

I tried to make a gradiant using playground then make it into a subclass of uiview to use it in my codebase.
The playground code is like this:
let view = UIView(frame: CGRect(x: 0, y: 0, width: 640, height: 41
))
let gradient: CAGradientLayer = CAGradientLayer(layer: view.layer)
gradient.frame = view.frame
let lightColor = UIColor(red: 157/256, green: 157/256, blue: 154/256, alpha: 1)
let darkColor = UIColor(red: 108/256, green: 104/256, blue: 104/256, alpha: 1)
gradient.colors = [lightColor.CGColor, darkColor.CGColor]
gradient.locations = [0.6 , 0.4]
gradient.startPoint = CGPoint(x: 1, y: 0.55)
gradient.endPoint = CGPoint(x: 0, y: 0.45)
view.layer.insertSublayer(gradient, atIndex: 0)
view //displayed
And display like this:
I tried to make it into my codebase with:
class GradiantView : UIView {
override var frame: CGRect {
didSet {
let gradient: CAGradientLayer = CAGradientLayer(layer: layer)
gradient.frame = bounds
let lightColor = UIColor(red: 157/256, green: 157/256, blue: 154/256, alpha: 1)
let darkColor = UIColor(red: 108/256, green: 104/256, blue: 104/256, alpha: 1)
gradient.colors = [lightColor.CGColor, darkColor.CGColor]
gradient.locations = [0.6 , 0.4]
gradient.startPoint = CGPoint(x: 1, y: 0.55)
gradient.endPoint = CGPoint(x: 0, y: 0.45)
layer.insertSublayer(gradient, atIndex: 0)
}
}
}
However, the result is like this: (no gradiant applied)
What happened and how to fix it ?
I inverted the locations and it seems to work.
I welcome any explanation on the difference between simulator and playground.
gradientLayer.locations = [0.4 , 0.6]

Drawing Polygons in Swift

I need to highlight an irregular shape when the user taps on it. My idea on how to do it was to draw a polygon that matches the shape, fill it with a color and change the opacity to make it translucent. Unfortunately I can't find anything on how to do this. Essentially, I want to draw the filled polygon, overlay it on to my map and then be able to dismiss (or hide) it. How can I accomplish this?
You probably want to use a CAShapeLayer. Here's a demo:
import XCPlayground
import UIKit
import CoreText
let view = UIView(frame: CGRectMake(0, 0, 300, 300))
XCPShowView("view", view)
let imageView = UIImageView(image: UIImage(named: "profile.jpg"))
imageView.frame = view.bounds
imageView.contentMode = UIViewContentMode.ScaleAspectFill
view.addSubview(imageView)
let shape = CAShapeLayer()
view.layer.addSublayer(shape)
shape.opacity = 0.5
shape.lineWidth = 2
shape.lineJoin = kCALineJoinMiter
shape.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).CGColor
shape.fillColor = UIColor(hue: 0.786, saturation: 0.15, brightness: 0.89, alpha: 1.0).CGColor
let path = UIBezierPath()
path.moveToPoint(CGPointMake(120, 20))
path.addLineToPoint(CGPointMake(230, 90))
path.addLineToPoint(CGPointMake(240, 250))
path.addLineToPoint(CGPointMake(40, 280))
path.addLineToPoint(CGPointMake(100, 150))
path.closePath()
shape.path = path.CGPath
Result:
Swift 3:
let shape = CAShapeLayer()
cell.layer.addSublayer(shape)
shape.opacity = 0.5
shape.lineWidth = 2
shape.lineJoin = kCALineJoinMiter
shape.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).cgColor
shape.fillColor = UIColor(hue: 0.786, saturation: 0.15, brightness: 0.89, alpha: 1.0).cgColor
let path = UIBezierPath()
path.move(to: CGPoint(x: 120, y: 20))
path.addLine(to: CGPoint(x: 230, y: 90))
path.addLine(to: CGPoint(x: 240, y: 250))
path.addLine(to: CGPoint(x: 100, y: 150))
path.close()
shape.path = path.cgPath

Resources