11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

iOSAdvent Calendar 2021

Day 9

SwiftUIでかんたんにパーティクルを表示する

Last updated at Posted at 2021-12-08

概要

SwiftUIで、以下のような、ボタンを押すとスパークする画面効果を使ってみたいと思います。

Simulator Screen Recording - iPod touch (7th generation) - 2021-12-06 at 15.18.02.gif

手順

今回のパーティクルはSpriteKitを使って実現します。

パーティクルファイルの用意

New Fileより、 SpriteKit Particle Fileを選択し、新しいパーティクルファイルを作成します。
パーティクルファイルには、FireSnow など様々なテンプレートが用意されているので、これだけでもいい感じのアニメーションが実現できます。

スクリーンショット 2021-12-06 15.20.23.png

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 完成のコード

SKSceneView
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])
    }
}
ContentView
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)
                }
            }
        }
    }
}

PreviewのRunでも、パーティクルの動作を確認することができます。
パーティクルのPreview Run

11
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?