Reputation: 3011
Background
I have a function that creates a core animation emitter layer that animates myImage1
, in the code below.
I want to change myImage1
to myImage2
to myImage3
and back to myImage1
after a delay of 10 seconds or every time a button is tapped.
I’ve tried unsuccessfully. The code myEmitterChange()
is executed but the image doesn’t change in the core animation emitter layer. What needs to be corrected in the code below?
Questions
1 - How do I change the emitter layer image once the CAEmitterLayer is added to a view ?
2 - How do I completely stop the CAEmitterLayer animation and remove it entirely from the view?
Code
import UIKit
class ViewController: UIViewController {
var myEmitterLayer = CAEmitterLayer()
var myEmitterCell = CAEmitterCell()
override func viewDidLoad() {
myEmitter()
self.perform(#selector(self.myEmitterChange), with: nil, afterDelay: 10)
}
@objc func myEmitterChange() {
print("Did I Change?")
myEmitterCell.color = UIColor.orange.cgColor
myEmitterCell.contents = UIImage(named: "myImage2")!.cgImage
}
func myEmitter() {
myEmitterCell.birthRate = 1
myEmitterCell.color = UIColor.blue.cgColor
myEmitterCell.contents = UIImage(named: "myImage1")!.cgImage
myEmitterCell.lifetime = 15
myEmitterCell.scale = 0.25
myEmitterCell.scaleSpeed = 0.025
myEmitterCell.velocity = 50
myEmitterCell.velocityRange = 50
myEmitterCell.spin = -2
myEmitterLayer.beginTime = CACurrentMediaTime()
myEmitterLayer.birthRate = 1
myEmitterLayer.emitterMode = CAEmitterLayerEmitterMode.outline
myEmitterLayer.emitterPosition = CGPoint(x: (view.bounds.size.width * 0.5), y: (view.bounds.size.height * 0.5))
myEmitterLayer.emitterShape = CAEmitterLayerEmitterShape.circle
myEmitterLayer.emitterSize = CGSize(width: 10, height: 10)
myEmitterLayer.renderMode = CAEmitterLayerRenderMode.oldestLast
myEmitterLayer.emitterCells = [myEmitterCell]
view.layer.addSublayer(myEmitterLayer)
}
}
Upvotes: -1
Views: 322
Reputation: 3011
Changing the image
1 - Add in the myEmitter()
function a name
property to myEmitterCell
.
myEmitterCell.name = "myEmitterCellName"
2 - Add in the myEmitterChange()
function a setValue
method to myEmitterLayer
.
myEmitterLayer.setValue(UIColor.orange.cgColor, forKeyPath: "emitterCells.myEmitterCellName.color")
myEmitterLayer.setValue(UIImage(named: "myImage2")!.cgImage, forKeyPath: "emitterCells.myEmitterCellName.contents")
3 - Remove in the myEmitterChange()
function the myEmitterCell.color
and myEmitterCell.contents
lines.
// myEmitterCell.color = UIColor.orange.cgColor
// myEmitterCell.contents = UIImage(named: "myImage2")!.cgImage
Stopping the animation
1 - Add in the myEmitterStop()
function a setValue
method to myEmitterLayer
.
myEmitterLayer.setValue(0, forKeyPath: "emitterCells.myEmitterCellName.birthRate")
Code
import UIKit
class ViewController: UIViewController {
var myEmitterLayer = CAEmitterLayer()
var myEmitterCell = CAEmitterCell()
override func viewDidLoad() {
myEmitter()
self.perform(#selector(self.myEmitterChange), with: nil, afterDelay: 10)
self.perform(#selector(self.myEmitterStop), with: nil, afterDelay: 20) // <- Add this line
}
@objc func myEmitterStop() {
print("Did I Stop?")
myEmitterLayer.setValue(0, forKeyPath: "emitterCells.myEmitterCellName.birthRate") // <- Add this line
}
@objc func myEmitterChange() {
print("Did I Change?")
// myEmitterCell.color = UIColor.orange.cgColor // <- Remove this line
// myEmitterCell.contents = UIImage(named: "myImage2")!.cgImage // <- Remove this line
myEmitterLayer.setValue(UIColor.orange.cgColor, forKeyPath: "emitterCells.myEmitterCellName.color") // <- Add this line
myEmitterLayer.setValue(UIImage(named: "myImage2")!.cgImage, forKeyPath: "emitterCells.myEmitterCellName.contents") // <- Add this line
}
func myEmitter() {
myEmitterCell.name = "myEmitterCellName" // <- Add this line
myEmitterCell.birthRate = 1
myEmitterCell.color = UIColor.blue.cgColor
myEmitterCell.contents = UIImage(named: "myImage1")!.cgImage
myEmitterCell.lifetime = 15
myEmitterCell.scale = 0.25
myEmitterCell.scaleSpeed = 0.025
myEmitterCell.velocity = 50
myEmitterCell.velocityRange = 50
myEmitterCell.spin = -2
myEmitterLayer.beginTime = CACurrentMediaTime()
myEmitterLayer.birthRate = 1
myEmitterLayer.emitterMode = CAEmitterLayerEmitterMode.outline
myEmitterLayer.emitterPosition = CGPoint(x: (view.bounds.size.width * 0.5), y: (view.bounds.size.height * 0.5))
myEmitterLayer.emitterShape = CAEmitterLayerEmitterShape.circle
myEmitterLayer.emitterSize = CGSize(width: 10, height: 10)
myEmitterLayer.renderMode = CAEmitterLayerRenderMode.oldestLast
myEmitterLayer.emitterCells = [myEmitterCell]
view.layer.addSublayer(myEmitterLayer)
}
}
Upvotes: 2