概要
SwiftUIで、以下のような、ボタンを押すとスパークする画面効果を使ってみたいと思います。
手順
今回のパーティクルはSpriteKit
を使って実現します。
パーティクルファイルの用意
New Fileより、 SpriteKit Particle File
を選択し、新しいパーティクルファイルを作成します。
パーティクルファイルには、Fire
や Snow
など様々なテンプレートが用意されているので、これだけでもいい感じのアニメーションが実現できます。
SwiftUI側の実装
SwiftUIで実装するのは以下です。
- import SpriteKit
- GeometryReaderを通してのSKSceneの作成
- SpriteViewの配置
SKSceneの用意
パーティクルを表示させるためのSKSceneを作成します。
まずは先ほど作ったパーティクルファイルをSKEmitterNode
として読み込み、SKSceneを作成し、addChildで追加を行います。
そのままではParticleのバックグラウンドの色も同時に表示するため、透明にしたい場合はbackgroundColorの設定も必要です。
SKSceneはsizeのプロパティのinitで作成を行う必要があるため、CGSizeが必要になります。
let emitterNode = SKEmitterNode(fileNamed: "SparkParticle")! //作成したパーティクルのファイル名
let scene = SKScene(size: size)
scene.backgroundColor = .clear
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5) //中央にパーティクルを配置
scene.addChild(emitterNode)
SpriteView
SwiftUIにはSpriteView
というクラスが用意されています。
これはSpriteKitで表現されるUIをSwiftUI上で表示することができるViewになります。
これに、先ほど用意したSKSceneを割り当てます。
前出の通り、SKSceneにはCGSizeが必要になるので、GeometryReader
を通してサイズを取得し、SKSceneに与えます。
SpriteViewを透明にしたい場合、SpriteViewのoptionにallowsTransparency
を与える必要があります。
SwiftUI 完成のコード
struct SKSceneView: View {
let size: CGSize
private var scene: SKScene {
let emitterNode = SKEmitterNode(fileNamed: "SparkParticle")! //作成したパーティクルのファイル名
let scene = SKScene(size: size)
scene.backgroundColor = .clear
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5) //中央にパーティクルを配置
scene.addChild(emitterNode)
return scene
}
var body: some View {
SpriteView(scene: scene, options: [.allowsTransparency])
}
}
struct ContentView: View {
@State
private var isFire: Bool = false
var body: some View {
ZStack {
Button {
isFire = true
} label: {
Text("Fire!")
}
if isFire {
GeometryReader { geometry in
SKSceneView(size: geometry.size)
}
}
}
}
}