Cannot change color of SCNCone - Scenekit - swift

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)

Related

How to fix: gradient background at landscaping?

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
}

Can i use 'for' loop on this?

I'm wondering if i may use 'for' loop for this code. Please forgive me, I know that is kind of a lame question, but I'm new to swift. Hope that you can help me here, guys!
Thanks a lot everyone!
Code:
override func viewDidLoad() {
super.viewDidLoad()
// Background color
let kolorTla = UIColor(red: 0/255.0, green: 66/255.0, blue: 132/255.0, alpha: 1.0)
view.backgroundColor = kolorTla
// Icons border
ramka.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
ramka.layer.cornerRadius = 5.0
ramka.layer.borderWidth = 3
// Image
skill1.image = UIImage(named: "english")
// Image border
skill1.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill1.layer.cornerRadius = 5.0
skill1.layer.borderWidth = 3
skill1.contentMode = .scaleAspectFit
// Image
skill2.image = UIImage(named: "literature")
// Image border
skill2.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill2.layer.cornerRadius = 5.0
skill2.layer.borderWidth = 3
skill2.contentMode = .scaleAspectFit
// Image
skill3.image = UIImage(named: "idea1")
// Image border
skill3.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill3.layer.cornerRadius = 5.0
skill3.layer.borderWidth = 3
skill3.contentMode = .scaleAspectFit
You can to some extent. You would just need to define an array of your items and loop over them. Not sure if it saves you much code wise but does make it a little more understandable.
override func viewDidLoad() {
super.viewDidLoad()
// Background color
let kolorTla = UIColor(red: 0/255.0, green: 66/255.0, blue: 132/255.0, alpha: 1.0)
view.backgroundColor = kolorTla
// Icons border
ramka.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
ramka.layer.cornerRadius = 5.0
ramka.layer.borderWidth = 3
// Set Image
skill1.image = UIImage(named: "english")
skill2.image = UIImage(named: "literature")
skill3.image = UIImage(named: "idea1")
// Set Image border
for skill in [skill1, skill2, skill3] {
skill.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill.layer.cornerRadius = 5.0
skill.layer.borderWidth = 3
skill.contentMode = .scaleAspectFit
}
}
Better approach at least in my opinion would be to create a simple function to handle this instead.
override func viewDidLoad() {
super.viewDidLoad()
// Background color
let kolorTla = UIColor(red: 0/255.0, green: 66/255.0, blue: 132/255.0, alpha: 1.0)
view.backgroundColor = kolorTla
// Icons border
ramka.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
ramka.layer.cornerRadius = 5.0
ramka.layer.borderWidth = 3
// Set Images
setupImageView(imageView: skill1, imageName: "english")
setupImageView(imageView: skill2, imageName: "literature")
setupImageView(imageView: skill3, imageName: "idea1")
}
func setupImageView(imageView: UIImageView, imageName: String) {
// Set Image
imageView.image = UIImage(named: imageName)
// Set Image border
imageView.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
imageView.layer.cornerRadius = 5.0
imageView.layer.borderWidth = 3
imageView.contentMode = .scaleAspectFit
}
While you're not able to use a for loop to modify the variable names and loop through them, you could put your skill instances in an array and loop through them that way.
...
skill1.image = UIImage(named: "english")
skill2.image = UIImage(named: "literature")
skill3.image = UIImage(named: "idea1")
let skills = [skill1, skill2, skill3]
for skill in skills {
skill.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill.layer.cornerRadius = 5.0
skill.layer.borderWidth = 3
skill.contentMode = .scaleAspectFit
}
Yes, you can. Place skill1,skill2, and skill3 in an array and iterate over it like this:
var objectArray = [skill1,skill2,skill3]
for object in objectArray
{
object.layer = ....
}
You could just extend your ImageView
extension UIImageView {
func addCustomLayer() { // add arguments to function if you wish to change the value assigned
self.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
self.layer.cornerRadius = 5.0
self.layer.borderWidth = 3
self.contentMode = .scaleAspectFit
}
}
}
Then you call that method on each UIImageView
for each in [skill1, skill2, skill3] {
each.addCustomLayer()
}

Gradient color effect on UIView in iOS 10 Swift 2.3 Xcode 8

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
}

A cube structure from image, and rotation

After long time with iOS, I never had 3D experience, and now I need to create 1 cube that can be rotated.
I am trying to figure out how to create a cube from an image , and rotate it in swift.
This link https://www.raywenderlich.com/12667/how-to-rotate-a-3d-object-using-touches-with-opengl has made exactly that but its not swift.
His other tutorials for swift are much more complex.
I am looking to have 2 functions :
create a 3d cube from image
rotate it to a certain x,y,z
Is there a simple Apple 3D animation class to that ?
import UIKit
import SceneKit
import QuartzCore
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
let scnView = self.view as! SCNView
scnView.scene = scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
cameraNode.position = SCNVector3(x: 0, y: 0, z: 15) //where will be situated a cube
scnView.allowsCameraControl = true //that's for you can spin it any direction with your finger if you are bored
scnView.autoenablesDefaultLighting = true //Lightting
var geometries = [
SCNBox(width: 4.0, height: 4.0, length: 4.0, chamferRadius: 0),
] //This is the cube with parameters of 4
var materials = [SCNMaterial]()
for i in 1...6 {
let material = SCNMaterial()
if i == 1 { material.diffuse.contents = UIImage (named: "qr.png") }
if i == 2 { material.diffuse.contents = UIColor(red: 0.6784, green: 0.698, blue: 0.7412, alpha: 1.0) }
if i == 3 { material.diffuse.contents = UIColor(red: 0.6784, green: 0.698, blue: 0.7412, alpha: 1.0) }
if i == 4 { material.diffuse.contents = UIColor(red: 0.6784, green: 0.698, blue: 0.7412, alpha: 1.0) }
if i == 5 { material.diffuse.contents = UIColor(red: 0.6784, green: 0.698, blue: 0.7412, alpha: 1.0) }
if i == 6 { material.diffuse.contents = UIColor(red: 0.7882, green: 0.7961, blue: 0.8863, alpha: 1.0) }
materials.append(material)
} //this is to coloring each side of cube
for i in 0..<geometries.count {
let geometry = geometries[i]
let node = SCNNode(geometry: geometry)
node.geometry?.materials = materials
node.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: 1, y: 1, z: 1, duration: 5)))
scene.rootNode.addChildNode(node)
}
}

Can't display an UIBezierPath

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)