[Swift]SpriteKit을 이용하여 UIView에 눈 내리는 효과 만들기
19 November 2015
슬슬 겨울이 다가와 버린 11월 말, 서비스 내에서도 겨울맞이 이벤트 등을 할 때가 있는데요. 그런 이벤트 맞이하여 화면에서 눈이 떨어지는 효과를 추가해보겠습니다.
눈 효과 파티클 만들기
프로젝트 생성 후 파티클을 생성합니다.
파티클 이름을 snow.sks
로 지정한 후, 눈 내리는 효과를 보여줄 Scene을 만듭니다.
class SnowScene: SKScene {
private var presentingView: SKView?
private var emitter: SKEmitterNode?
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
scaleMode = .ResizeFill
backgroundColor = UIColor.clearColor()
presentingView = view
}
// 눈 내리는 효과 시작
func startEmitter() {
emitter = SKEmitterNode(fileNamed: "snow.sks")
guard
let emitter = emitter,
let presentingView = presentingView
else { return }
emitter.particlePositionRange = CGVectorMake(CGRectGetWidth(presentingView.bounds), 0)
emitter.position = CGPointMake(CGRectGetMidX(presentingView.bounds), CGRectGetHeight(presentingView.bounds))
emitter.targetNode = self
addChild(emitter)
}
// 눈 내리는 효과 정지
func stopEmitter() {
guard let emitter = emitter else { return }
emitter.particleBirthRate = 0.0
emitter.targetNode = nil
emitter.removeFromParent()
self.emitter = nil
}
}
그리고 메인 ViewController에서 SnowScene을 보여줄 SKView, SnowScene 변수를 선언합니다.
@IBOutlet weak private var snowView: UIView!
private var sceneView: SKView?
private var snowScene: SnowScene?
이제 sceneView와 snowScene을 생성하여 UIView인 snowView에 붙여줍니다.
override func viewDidLoad() {
super.viewDidLoad()
sceneView = SKView(frame: self.view.frame)
snowScene = SnowScene()
guard
let sceneView = sceneView,
let snowScene = snowScene
else { return }
sceneView.backgroundColor = UIColor.clearColor()
sceneView.presentScene(snowScene)
snowView.addSubview(sceneView)
// 밑에 있는 뷰가 터치를 먹도록 설정
sceneView.userInteractionEnabled = false
snowView.userInteractionEnabled = false
}
그리고 화면이 나타나면 눈 내리는 효과를 시작하도록 합니다.
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
guard let snowScene = snowScene else { return }
snowScene.startEmitter()
}
그리고 화면이 사라지면 sceneView를 정리하고 눈 내리는 효과를 끕니다.
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
guard
let snowScene = snowScene,
let sceneView = sceneView
else { return }
sceneView.presentScene(nil)
sceneView.removeFromSuperview()
snowScene.stopEmitter()
}
특정 기간이 되거나 서버에서 눈 내리는 효과를 보여주라고 전달하면 눈 내리는 효과를 보여주면 됩니다.
주의 : sceneView의 presentScene을 정리하지 않으면 계속 살아있기 때문에 성능에 영향을 줍니다. 따라서 여러 번 실행하여 성능에 문제가 없는지 확인을 하는 것이 중요합니다. 또한, sceneView와 snowScene의 userInteractionEnabled를 false로 설정하여 아래에 있는 뷰에 터치를 보내줄 수 있도록 합니다.
여기에서 ViewController와 SnowScene 전체 소스를 받으시면 됩니다.