I'm trying to display an UIBezierPath in a view. That's the object:
let color = UIColor(red: 0.651, green: 1.000, blue: 0.000, alpha: 1.000).setFill()
let rectanglePath = UIBezierPath(rect: CGRectMake(15, 0, 8, 120))
rectanglePath.fill()
but, when run, xCode displays just a lot messages in console and none in the simulator!
I tried following these solutions How can I set CG_CONTEXT_SHOW_BACKTRACE environmental variable? but is the same (and, in their opinion, issue should be solved in with iOS 9.1).
Here's an example code.
Just change the code:
let shapeLayer = CAShapeLayer()
let color = UIColor(red: 0.651, green: 1.000, blue: 0.000, alpha: 1.000).CGColor
let rectanglePath = UIBezierPath(rect: CGRectMake(15, 0, 8, 120))
shapeLayer.path = rectanglePath
shapeLayer.fillColor = color
self.view.layer.addSublayer(shapeLayer)
Related
I have this code which creates a gradient background.
When I rotate the deviace to landscape mode, the gradient background doesnt fill up to the whole size of the screen, some parts are white.
My goal is the whenever the orrientation changes, the gradient should fill the whole screen.
let gradient: CAGradientLayer = CAGradientLayer()
let color1 = UIColor(red: 198.0/255.0 , green: 255.0/255.0, blue: 221.0/255.0, alpha: 1.0).cgColor
let color2 = UIColor(red: 251.0/255.0, green: 215.0/255.0, blue: 134.0/255.0, alpha: 1.0).cgColor
let color3 = UIColor(red: 247.0/255.0, green: 121.0/255.0, blue: 125.0/255.0, alpha: 1.0).cgColor
gradient.name="asd"
gradient.colors = [color1,color2,color3]
gradient.locations = [0.0 , 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
gradient.frame = CGRect(x: 0.0, y: 0.0, width: wid, height: heu)
self.view.layer.insertSublayer(gradient, at: 0)
}
Hold the gradient layer as a property and update its frame in layoutSubview()
var gradientLayer: CAGradientLayer?
override func viewDidLoad() {
super.viewDidLoad()
///
/// YOUR CODE
///
gradientLayer = gradient
}
override func layoutSubviews() {
super.layoutSubviews()
gradientLayer?.frame = self.view.bounds
}
CGRect not appearing at the same time as gradient sublayer, it's one or the other
Drawing only the gradient layer or only the rectangle works fine.
guard let ctx = UIGraphicsGetCurrentContext() else { fatalError() }
ctx.setFillColor(red: 1, green: 0.5, blue: 0.5, alpha: 1)
let segment1 = CGRect(x: 20, y: 110, width: 30, height: 10)
ctx.fill(segment1)
let gradient = CAGradientLayer()
gradient.frame = bounds
gradient.colors = [UIColor.init(displayP3Red: 0.29, green: 0.56, blue: 1.0, alpha: 1).cgColor, UIColor.init(displayP3Red: 0.23, green: 0.19, blue: 0.8, alpha: 1).cgColor]
layer.insertSublayer(gradient, at: 0)
I was expecting them both to appear in the correct order
Use: gradient.render(in: ctx) instead of layer.insertSublayer(gradient, at: 0 and draw segement1 after that: (Assuming you are doing this in a custom view class)
class customView: UIView {
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { fatalError() }
let gradient = CAGradientLayer()
gradient.frame = bounds
gradient.colors = [UIColor.init(displayP3Red: 0.29, green: 0.56, blue: 1.0, alpha: 1).cgColor, UIColor.init(displayP3Red: 0.23, green: 0.19, blue: 0.8, alpha: 1).cgColor]
gradient.render(in: ctx)
ctx.setFillColor(red: 1, green: 0.5, blue: 0.5, alpha: 1)
let segment1 = CGRect(x: 20, y: 110, width: 30, height: 10)
ctx.fill(segment1)
}
}
This way you aren't using the CGGraphicsContext in addition to the CALayer, you are just using the CGGraphicsContext because you layer gets rendered using the ctx
I am not sure if I understand the concept of Masking correctly but I am trying to recreate the Twitter logo expansion animation in their app:
Twitter Logo expansion
I have this code so far:
class LaunchScreenViewController: UIViewController {
var mask: CALayer!
override func viewDidLoad() {
setUpViewMask()
}
func setUpViewMask() {
mask = CALayer()
mask.contents = UIImage(named: "logo_mask")?.cgImage
mask.contentsGravity = kCAGravityResizeAspect
mask!.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
mask!.anchorPoint = CGPoint(x: 0.5, y: 0.5)
mask!.position = CGPoint(x: view.frame.size.width/2, y: view.frame.size.height/2)
view.layer.backgroundColor = UIColor(red: 70/255, green: 154/255, blue: 233/255, alpha: 1).cgColor
view.layer.mask = mask
}
}
The output of this is:
How would I change the black background to be blue? I tried doing but it didn't seem to work:
view.layer.backgroundColor = UIColor(red: 70/255, green: 154/255, blue: 233/255, alpha: 1).cgColor
Create an intermediate layer where you apply mask. Set the background of your view to the desired background, and set background color of the intermediate layer to the color that you wish your mask to appear in. Something like this,
view.backgroundColor = UIColor(red: 70/255, green: 154/255, blue: 233/255, alpha: 1) // set background of the view portion that do not include mask
let parentLayer = CALayer()
parentLayer.frame = view.bounds
parentLayer.backgroundColor = UIColor.white.cgColor // sets background of mask
view.layer.addSublayer(parentLayer)
let mask = CALayer()
mask.contents = UIImage(named: "twitter.png")?.cgImage
mask.contentsGravity = kCAGravityResizeAspect
mask.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
mask.anchorPoint = CGPoint(x: 0.5, y: 0.5)
mask.position = CGPoint(x: view.frame.size.width/2, y: view.frame.size.height/2)
parentLayer.mask = mask
This can be achieved by changing the background color of appDelegate's window...
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window!.backgroundColor = UIColor.blue
I have an 'attach node' that has 2 child nodes that are Blender models. I have added a third node to this attach node that is a SCNCone. For some reason, I can't change the color of the cone node, only the transparency. I can't seem to see anything wrong with the code, but during runtime the cone is always a black color no matter what color I set it to.
let coneGeo = SCNCone(topRadius: 0.1, bottomRadius: 0.7, height: 4)
let coneMaterial = SCNMaterial()
coneMaterial.diffuse.contents = UIColor(red: 255.0/255.0, green: 108.0/255.0, blue: 91.0/255.0, alpha: 0.2)
coneGeo.materials = [coneMaterial]
let coneNode = SCNNode(geometry: coneGeo)
coneNode.position = SCNVector3(0, -1.5, 0)
coneNode.name = "coneNode"
AttachNode.addChildNode(coneNode)
Replace coneMaterial.diffuse.contents = UIColor(red: 255.0/255.0, green: 108.0/255.0, blue: 91.0/255.0, alpha: 0.2) with coneGeo.geometry?.firstMaterial?.diffuse.contents.diffuse.contents = UIColor(red: 255.0/255.0, green: 108.0/255.0, blue: 91.0/255.0, alpha: 0.2). Instead of changing the cone's material color without geometry, you have to access it's material color through it's geometry parameter.
coneGeo.materials = [coneMaterial]
This will also work. I tested your code by adding the cone node to an empty scene.
I just get a black screen.
But if I change the alpha value to say 0.5, this is what I get.
The code.
override func viewDidLoad()
{
super.viewDidLoad()
// create a new scene
let scene = SCNScene()
let coneGeo = SCNCone(topRadius: 0.1, bottomRadius: 0.7, height: 4)
let coneMaterial = SCNMaterial()
coneMaterial.diffuse.contents = UIColor(red: 255.0 / 255.0,
green: 108.0 / 255.0,
blue: 91.0 / 255.0, alpha: 0.5)
coneGeo.materials = [coneMaterial]
let coneNode = SCNNode(geometry
: coneGeo)
coneNode.position = SCNVector3(0, -1.5, 0)
coneNode.name = "coneNode"
scene.rootNode.addChildNode(coneNode)
// retrieve the SCNView
let scnView = self.view as! SCNView
// set the scene to the view
scnView.scene = scene
// allows the user to manipulate the camera
scnView.allowsCameraControl = true
// show statistics such as fps and timing information
scnView.showsStatistics = true
// configure the view
scnView.backgroundColor = UIColor.black
}
So I would say, check your alpha value in UIColor(red: 255.0/255.0, green: 108.0/255.0, blue: 91.0/255.0, alpha: 0.2)
I am trying to achieve a gradient color on a UIView or button with two color black which fades out to clear color or white color (please see image).
I have tried using different combinations of white color, clear color; experimenting with alpha as well. I have also set the locations property as can be seen in below code but I am not able to achieve desired results.
Can anyone tell me where I am wrong. :)
let colorClear = UIColor.clearColor().CGColor
let colorLeft = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 0.9).CGColor
let colorRight = UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 1.0).CGColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorLeft, colorRight]
gradientLayer.locations = [ 0.1, 0.9]
gradientLayer.frame = self.createAccountView.bounds
gradientLayer.startPoint = CGPoint(x:0.0, y:0.5)
gradientLayer.endPoint = CGPoint(x:1.0, y:0.5)
createAccountView.layer.addSublayer(gradientLayer)
createAccountView.layer.masksToBounds = true
The desired result is the one in which black color transitions to a faded one.
I have already tried setting both colors as black and the color1 with an alpha.
I have already tried commenting locations property.
you should set gradientLayer.frame in viewDidLayoutSubviews().
Like this:
class ViewController: UIViewController {
let gradientLayer = CAGradientLayer()
override func viewDidLoad() {
let colorClear = UIColor.clearColor().CGColor
let colorLeft = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 0.9).CGColor
let colorRight = UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 1.0).CGColor
self.gradientLayer.colors = [colorLeft, colorRight]
self.gradientLayer.locations = [ 0.1, 0.9]
self.gradientLayer.startPoint = CGPoint(x:0.0, y:0.5)
self.gradientLayer.endPoint = CGPoint(x:1.0, y:0.5)
createAccountView.layer.addSublayer(self.gradientLayer)
createAccountView.layer.masksToBounds = true
}
override viewDidLayoutSubviews() {
super.viewDidLayoutSubViews()
self.gradientLayer.frame = self.createAccountView.bounds
}