├── ScreenShot.png
├── Assets.xcassets
├── Contents.json
├── Particle Sprite Atlas.spriteatlas
│ ├── Contents.json
│ ├── snow.imageset
│ │ ├── snow.png
│ │ └── Contents.json
│ ├── star.imageset
│ │ ├── star.png
│ │ └── Contents.json
│ ├── bokeh.imageset
│ │ ├── bokeh.png
│ │ └── Contents.json
│ ├── spark.imageset
│ │ ├── spark.png
│ │ └── Contents.json
│ ├── circle.imageset
│ │ ├── circle.png
│ │ └── Contents.json
│ ├── tspark.imageset
│ │ ├── tspark.png
│ │ └── Contents.json
│ └── confetti.imageset
│ │ ├── confetti.png
│ │ └── Contents.json
├── seattle.imageset
│ ├── seattle.png
│ └── Contents.json
├── birthday-cake.imageset
│ ├── birthday-cake.png
│ └── Contents.json
└── AppIcon.appiconset
│ └── Contents.json
├── FunWithParticleEmitters
├── Fire.sks
├── Rain.sks
├── Smoke.sks
├── Spark.sks
├── snow.png
├── Assets.xcassets
│ ├── Contents.json
│ └── Particle Sprite Atlas.spriteatlas
│ │ ├── Contents.json
│ │ ├── bokeh.imageset
│ │ ├── bokeh.png
│ │ └── Contents.json
│ │ └── spark.imageset
│ │ ├── spark.png
│ │ └── Contents.json
├── tspark.png
├── confetti.png
├── Custom Views
│ ├── GradientView.swift
│ ├── ConfettiParticleView.swift
│ ├── SnowParticleView.swift
│ └── FireworksParticleView.swift
├── Extensions
│ ├── NSLayoutConstraints+Extentsions.swift
│ └── UIViewController+Extensions.swift
├── View Controllers
│ ├── ContainerViewController.swift
│ ├── ConfettiViewController.swift
│ ├── FireworksViewController.swift
│ └── SnowViewController.swift
├── Info.plist
├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.storyboard
└── AppDelegate.swift
├── README.MD
├── FunWithParticleEmitters.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── project.pbxproj
└── .gitignore
/ScreenShot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/ScreenShot.png
--------------------------------------------------------------------------------
/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Fire.sks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/FunWithParticleEmitters/Fire.sks
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Rain.sks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/FunWithParticleEmitters/Rain.sks
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Smoke.sks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/FunWithParticleEmitters/Smoke.sks
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Spark.sks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/FunWithParticleEmitters/Spark.sks
--------------------------------------------------------------------------------
/FunWithParticleEmitters/snow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/FunWithParticleEmitters/snow.png
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/FunWithParticleEmitters/tspark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/FunWithParticleEmitters/tspark.png
--------------------------------------------------------------------------------
/FunWithParticleEmitters/confetti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/FunWithParticleEmitters/confetti.png
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Assets.xcassets/seattle.imageset/seattle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/Assets.xcassets/seattle.imageset/seattle.png
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # FunWithParticleEmitters
2 | Example of Particle Emitter in iOS using Swift
3 |
4 | 
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Assets.xcassets/Particle Sprite Atlas.spriteatlas/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Assets.xcassets/birthday-cake.imageset/birthday-cake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/Assets.xcassets/birthday-cake.imageset/birthday-cake.png
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/snow.imageset/snow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/Assets.xcassets/Particle Sprite Atlas.spriteatlas/snow.imageset/snow.png
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/star.imageset/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/Assets.xcassets/Particle Sprite Atlas.spriteatlas/star.imageset/star.png
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/bokeh.imageset/bokeh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/Assets.xcassets/Particle Sprite Atlas.spriteatlas/bokeh.imageset/bokeh.png
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/spark.imageset/spark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/Assets.xcassets/Particle Sprite Atlas.spriteatlas/spark.imageset/spark.png
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/circle.imageset/circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/Assets.xcassets/Particle Sprite Atlas.spriteatlas/circle.imageset/circle.png
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/tspark.imageset/tspark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/Assets.xcassets/Particle Sprite Atlas.spriteatlas/tspark.imageset/tspark.png
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/confetti.imageset/confetti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/Assets.xcassets/Particle Sprite Atlas.spriteatlas/confetti.imageset/confetti.png
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Assets.xcassets/Particle Sprite Atlas.spriteatlas/bokeh.imageset/bokeh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/FunWithParticleEmitters/Assets.xcassets/Particle Sprite Atlas.spriteatlas/bokeh.imageset/bokeh.png
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Assets.xcassets/Particle Sprite Atlas.spriteatlas/spark.imageset/spark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkw5877/FunWithParticleEmitters/HEAD/FunWithParticleEmitters/Assets.xcassets/Particle Sprite Atlas.spriteatlas/spark.imageset/spark.png
--------------------------------------------------------------------------------
/FunWithParticleEmitters.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Assets.xcassets/seattle.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "seattle.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets.xcassets/birthday-cake.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "birthday-cake.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/bokeh.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "bokeh.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/circle.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "circle.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/snow.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "snow.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/spark.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "spark.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/star.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "star.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/tspark.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tspark.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets.xcassets/Particle Sprite Atlas.spriteatlas/confetti.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "confetti.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Custom Views/GradientView.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit
3 |
4 | class GradientView:UIView {
5 |
6 | var startColor:UIColor = .white
7 | var endColor:UIColor = .white
8 |
9 | override class var layerClass:AnyClass{
10 | return CAGradientLayer.self
11 | }
12 |
13 | override func layoutSubviews() {
14 | (layer as! CAGradientLayer).colors = [startColor.cgColor, endColor.cgColor]
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Assets.xcassets/Particle Sprite Atlas.spriteatlas/bokeh.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "bokeh.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Assets.xcassets/Particle Sprite Atlas.spriteatlas/spark.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "spark.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Extensions/NSLayoutConstraints+Extentsions.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit.NSLayoutConstraint
3 |
4 | extension NSLayoutConstraint {
5 |
6 | class func pin(view:UIView, to superview:UIView) {
7 | view.translatesAutoresizingMaskIntoConstraints = false
8 | NSLayoutConstraint.activate([
9 | view.topAnchor.constraint(equalTo: superview.topAnchor),
10 | view.trailingAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.trailingAnchor),
11 | view.leadingAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.leadingAnchor),
12 | view.bottomAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.bottomAnchor)
13 | ])
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/View Controllers/ContainerViewController.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit
3 |
4 | class ContainerViewController: UIViewController {
5 |
6 | let scrollView :UIScrollView = {
7 | let scrollView = UIScrollView()
8 | scrollView.translatesAutoresizingMaskIntoConstraints = false
9 | scrollView.isPagingEnabled = true
10 | scrollView.backgroundColor = .gray
11 | return scrollView
12 | }()
13 |
14 | let content = [SnowViewController(), ConfettiViewController(), FireworksViewController()]
15 |
16 | override var preferredStatusBarStyle: UIStatusBarStyle {
17 | return .lightContent
18 | }
19 |
20 | override func loadView() {
21 | view = UIView(frame: UIScreen.main.bounds)
22 | scrollView.frame = view.frame
23 | view.addSubview(scrollView)
24 | NSLayoutConstraint.pin(view: scrollView, to: view)
25 | }
26 |
27 | override func viewDidLoad() {
28 | super.viewDidLoad()
29 | configureChildren()
30 | }
31 |
32 | private func configureChildren() {
33 | for controller in content {
34 | add(child: controller, in: scrollView)
35 | controller.view.frame = view.frame
36 | controller.view.frame.origin.x = scrollView.contentSize.width
37 | scrollView.contentSize.width += view.frame.size.width
38 | }
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Custom Views/ConfettiParticleView.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit
3 |
4 | class ConfettiParticleView: UIView {
5 |
6 | var particleImage:UIImage?
7 |
8 | override class var layerClass:AnyClass {
9 | return CAEmitterLayer.self
10 | }
11 |
12 | func makeEmitterCell(color: UIColor) -> CAEmitterCell {
13 | let cell = CAEmitterCell()
14 | cell.birthRate = 3
15 | cell.lifetime = 7.0
16 | cell.lifetimeRange = 0
17 | cell.color = color.cgColor
18 | cell.velocity = 200
19 | cell.velocityRange = 50
20 | cell.emissionLongitude = .pi
21 | cell.emissionRange = .pi / 4
22 | cell.spin = 2
23 | cell.spinRange = 3
24 | cell.scale = 0.75
25 | cell.scaleRange = 0.5
26 | cell.scaleSpeed = -0.05
27 | cell.contents = particleImage?.cgImage
28 | return cell
29 | }
30 |
31 | override func layoutSubviews() {
32 | super.layoutSubviews()
33 | let emitter = self.layer as! CAEmitterLayer
34 | emitter.masksToBounds = true
35 | emitter.emitterShape = .line
36 | emitter.emitterPosition = CGPoint(x: bounds.midX, y: 0)
37 | emitter.emitterSize = CGSize(width: bounds.size.width, height: 1)
38 |
39 | let red = makeEmitterCell(color: UIColor.red)
40 | let green = makeEmitterCell(color: UIColor.green)
41 | let blue = makeEmitterCell(color: UIColor.blue)
42 | emitter.emitterCells = [red, green, blue]
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Custom Views/SnowParticleView.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit
3 |
4 | class SnowParticleView:UIView {
5 |
6 | var particleImage:UIImage?
7 |
8 | override class var layerClass:AnyClass {
9 | return CAEmitterLayer.self
10 | }
11 |
12 | func makeEmmiterCell(color:UIColor, velocity:CGFloat, scale:CGFloat)-> CAEmitterCell {
13 | let cell = CAEmitterCell()
14 | cell.birthRate = 10
15 | cell.lifetime = 20.0
16 | cell.lifetimeRange = 0
17 | cell.velocity = velocity
18 | cell.velocityRange = velocity / 4
19 | cell.emissionLongitude = .pi
20 | cell.emissionRange = .pi / 8
21 | cell.scale = scale
22 | cell.scaleRange = scale / 3
23 | cell.contents = particleImage?.cgImage
24 | return cell
25 | }
26 |
27 | override func layoutSubviews() {
28 | let emitter = self.layer as! CAEmitterLayer
29 | emitter.masksToBounds = true
30 | emitter.emitterShape = .line
31 | emitter.emitterPosition = CGPoint(x: bounds.midX, y: 0)
32 | emitter.emitterSize = CGSize(width: bounds.size.width, height: 1)
33 |
34 | let near = makeEmmiterCell(color: UIColor(white: 1, alpha: 1), velocity: 100, scale: 0.3)
35 | let middle = makeEmmiterCell(color: UIColor(white: 1, alpha: 0.66), velocity: 80, scale: 0.2)
36 | let far = makeEmmiterCell(color: UIColor(white: 1, alpha: 0.33), velocity: 60, scale: 0.1)
37 |
38 | emitter.emitterCells = [near, middle, far]
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UIStatusBarStyle
30 | UIStatusBarStyleLightContent
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | ## Playgrounds
32 | timeline.xctimeline
33 | playground.xcworkspace
34 |
35 | # Swift Package Manager
36 | #
37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
38 | # Packages/
39 | # Package.pins
40 | # Package.resolved
41 | .build/
42 |
43 | # CocoaPods
44 | #
45 | # We recommend against adding the Pods directory to your .gitignore. However
46 | # you should judge for yourself, the pros and cons are mentioned at:
47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
48 | #
49 | Pods/
50 |
51 | # Carthage
52 | #
53 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
54 | # Carthage/Checkouts
55 |
56 | Carthage/Build
57 |
58 | # fastlane
59 | #
60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
61 | # screenshots whenever they are needed.
62 | # For more information about the recommended setup visit:
63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
64 |
65 | fastlane/report.xml
66 | fastlane/Preview.html
67 | fastlane/screenshots/**/*.png
68 | fastlane/test_output
69 |
--------------------------------------------------------------------------------
/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Extensions/UIViewController+Extensions.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit.UIViewController
3 |
4 | extension UIViewController {
5 |
6 | /* remove child controller */
7 | func add(child childViewController: UIViewController) {
8 | beginAddChild(child: childViewController)
9 | view.addSubview(childViewController.view)
10 | endAddChild(child: childViewController)
11 | }
12 |
13 | /* add child controller in a specific view */
14 | func add(child childViewController: UIViewController, in view: UIView) {
15 | beginAddChild(child: childViewController)
16 | view.addSubview(childViewController.view)
17 | endAddChild(child: childViewController)
18 | }
19 |
20 | /* add child controller in a specific view with a set frame */
21 | func add(child childViewController: UIViewController, in view: UIView, with frame:CGRect) {
22 | beginAddChild(child: childViewController)
23 | childViewController.view.frame = frame
24 | view.addSubview(childViewController.view)
25 | endAddChild(child: childViewController)
26 | }
27 |
28 | /* remove child controller */
29 | func remove(child childViewController:UIViewController){
30 | childViewController.beginAppearanceTransition(false, animated: false)
31 | childViewController.willMove(toParent: nil)
32 | childViewController.view.removeFromSuperview()
33 | childViewController.removeFromParent()
34 | childViewController.endAppearanceTransition()
35 | }
36 |
37 | /* extract these common methods out to avoid code duplication */
38 | private func beginAddChild(child childViewController:UIViewController){
39 | childViewController.beginAppearanceTransition(true, animated: false)
40 | self.addChild(childViewController)
41 | }
42 |
43 | private func endAddChild(child childViewController:UIViewController){
44 | childViewController.didMove(toParent: self)
45 | childViewController.endAppearanceTransition()
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/View Controllers/ConfettiViewController.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit
3 |
4 | class ConfettiViewController : UIViewController {
5 |
6 | override func viewDidLoad() {
7 | super.viewDidLoad()
8 | let gradient = GradientView()
9 | gradient.startColor = UIColor(red: 0.53, green: 0.80, blue: 1.0, alpha: 1)
10 | gradient.endColor = UIColor(red: 0.8, green: 0.96, blue: 1.0, alpha: 1)
11 | gradient.translatesAutoresizingMaskIntoConstraints = false
12 | view.addSubview(gradient)
13 |
14 |
15 | let image = UIImage(named: "birthday-cake")
16 | let imageView = UIImageView(image: image)
17 | imageView.contentMode = .scaleAspectFit
18 | imageView.layer.masksToBounds = true
19 | imageView.translatesAutoresizingMaskIntoConstraints = false
20 | view.addSubview(imageView)
21 |
22 | let confetti = ConfettiParticleView()
23 | confetti.particleImage = UIImage(named: "confetti")
24 | confetti.translatesAutoresizingMaskIntoConstraints = false
25 | view.addSubview(confetti)
26 |
27 | NSLayoutConstraint.pin(view: gradient, to: view)
28 | NSLayoutConstraint.pin(view: confetti, to: view)
29 |
30 | NSLayoutConstraint.activate([
31 | imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
32 | imageView.heightAnchor.constraint(equalToConstant:200),
33 | imageView.widthAnchor.constraint(equalToConstant:200),
34 | imageView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant:-16)])
35 |
36 | let label = UILabel()
37 | label.translatesAutoresizingMaskIntoConstraints = false
38 | label.font = UIFont(name: "Menlo-Regular", size: 35)
39 | label.text = "Happy Birthday!"
40 | label.textAlignment = .center
41 | label.textColor = .blue
42 | label.sizeToFit()
43 | view.addSubview(label)
44 |
45 | NSLayoutConstraint.activate([
46 | label.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
47 | label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
48 | ])
49 |
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // FunWithParticleEmitters
4 | //
5 | // Created by user on 2/21/19.
6 | // Copyright © 2019 user. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | window = UIWindow(frame: UIScreen.main.bounds)
19 | window?.rootViewController = ContainerViewController()
20 | window?.makeKeyAndVisible()
21 | return true
22 | }
23 |
24 | func applicationWillResignActive(_ application: UIApplication) {
25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
27 | }
28 |
29 | func applicationDidEnterBackground(_ application: UIApplication) {
30 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
32 | }
33 |
34 | func applicationWillEnterForeground(_ application: UIApplication) {
35 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
36 | }
37 |
38 | func applicationDidBecomeActive(_ application: UIApplication) {
39 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
40 | }
41 |
42 | func applicationWillTerminate(_ application: UIApplication) {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 |
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/View Controllers/FireworksViewController.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit.UIViewController
3 |
4 | class FireworksViewController : UIViewController {
5 |
6 | var timer:Timer?
7 | let fireworks = FireworksParticleView()
8 |
9 | override func loadView() {
10 | let view = UIView()
11 | self.view = view
12 | }
13 |
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 |
17 | let sky = GradientView()
18 | sky.startColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1)
19 | sky.endColor = UIColor(red: 0.07, green: 0.04, blue: 0.66, alpha: 1)
20 | sky.translatesAutoresizingMaskIntoConstraints = false
21 | view.addSubview(sky)
22 |
23 | let image = UIImage(named: "seattle")
24 | let imageView = UIImageView(image: image)
25 | imageView.translatesAutoresizingMaskIntoConstraints = false
26 | imageView.contentMode = .scaleAspectFill
27 | imageView.layer.masksToBounds = true
28 |
29 | view.addSubview(imageView)
30 |
31 | NSLayoutConstraint.activate([
32 | imageView.heightAnchor.constraint(equalToConstant:300), imageView.leadingAnchor.constraint(equalTo:view.leadingAnchor), imageView.trailingAnchor.constraint(equalTo:view.trailingAnchor),
33 | imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
34 | ])
35 |
36 | NSLayoutConstraint.activate([
37 | sky.leadingAnchor.constraint(equalTo: view.leadingAnchor),
38 | sky.trailingAnchor.constraint(equalTo: view.trailingAnchor),
39 | sky.topAnchor.constraint(equalTo: view.topAnchor),
40 | sky.bottomAnchor.constraint(equalTo: imageView.topAnchor)])
41 |
42 | fireworks.particleImage = UIImage(named: "tspark")
43 | fireworks.flareImage = UIImage(named: "tspark")
44 | fireworks.translatesAutoresizingMaskIntoConstraints = false
45 | view.addSubview(fireworks)
46 |
47 | NSLayoutConstraint.activate([
48 | fireworks.leadingAnchor.constraint(equalTo: view.leadingAnchor),
49 | fireworks.trailingAnchor.constraint(equalTo: view.trailingAnchor),
50 | fireworks.topAnchor.constraint(equalTo: view.topAnchor),
51 | fireworks.bottomAnchor.constraint(equalTo: imageView.centerYAnchor)])
52 | }
53 |
54 | override func viewWillDisappear(_ animated: Bool) {
55 | super.viewWillDisappear(animated)
56 | timer?.invalidate()
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/View Controllers/SnowViewController.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit
3 |
4 | class SnowViewController : UIViewController {
5 |
6 | let snow = SnowParticleView()
7 | let button = UIButton()
8 |
9 | override func viewDidLoad() {
10 | super.viewDidLoad()
11 | let sky = GradientView()
12 | sky.translatesAutoresizingMaskIntoConstraints = false
13 | sky.startColor = UIColor(red: 0.1, green: 0.25, blue: 0.5, alpha: 1)
14 | sky.endColor = UIColor(red: 0.75, green: 0.8, blue: 0.9, alpha: 1)
15 | view.addSubview(sky)
16 |
17 | snow.translatesAutoresizingMaskIntoConstraints = false
18 | snow.isHidden = true
19 | snow.particleImage = UIImage(named: "snow")
20 | view.addSubview(snow)
21 |
22 |
23 | button.translatesAutoresizingMaskIntoConstraints = false
24 | button.backgroundColor = .white
25 | button.layer.cornerRadius = 10
26 | button.setTitle("Make it snow", for: .normal)
27 | button.setTitleColor(.blue, for: .normal)
28 | button.addTarget(self, action: #selector(makeItSnow(sender:)), for: .touchUpInside)
29 | view.addSubview(button)
30 |
31 | NSLayoutConstraint.activate([
32 | sky.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
33 | sky.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
34 | sky.topAnchor.constraint(equalTo: view.topAnchor),
35 | sky.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)])
36 |
37 | NSLayoutConstraint.activate([
38 | snow.leadingAnchor.constraint(equalTo: view.leadingAnchor),
39 | snow.trailingAnchor.constraint(equalTo: view.trailingAnchor),
40 | snow.topAnchor.constraint(equalTo: view.topAnchor),
41 | snow.bottomAnchor.constraint(equalTo: view.bottomAnchor)])
42 |
43 | NSLayoutConstraint.activate([
44 | button.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
45 | button.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant:16),
46 | button.widthAnchor.constraint(equalToConstant: 150)
47 | ])
48 | }
49 |
50 | @objc private func makeItSnow(sender:UIButton) {
51 | snow.isHidden.toggle()
52 | toggleButtonState()
53 | }
54 |
55 | private func toggleButtonState() {
56 | if button.title(for: .normal) == "Make it snow"{
57 | button.setTitle("Make it stop", for: .normal)
58 | button.setTitleColor(.red, for: .normal)
59 | } else{
60 | button.setTitle("Make it snow", for: .normal)
61 | button.setTitleColor(.blue, for: .normal)
62 | }
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters/Custom Views/FireworksParticleView.swift:
--------------------------------------------------------------------------------
1 |
2 | import UIKit.UIView
3 |
4 | class FireworksParticleView:UIView {
5 |
6 | var particleImage:UIImage?
7 | var flareImage:UIImage?
8 |
9 | override class var layerClass:AnyClass {
10 | return CAEmitterLayer.self
11 | }
12 |
13 | /*
14 | * Invisible particle representing the rocket before the explosion
15 | * The particle is invisible because we do not assign an image to the
16 | * contents property of the cell
17 | */
18 | func makeEmiterCellRocket() -> CAEmitterCell {
19 | let cell = CAEmitterCell()
20 | /* -pi/2 = up */
21 | cell.emissionLongitude = -.pi/2
22 | cell.emissionLatitude = 0
23 | cell.emissionRange = .pi/4
24 | cell.lifetime = 1.6
25 | cell.birthRate = 1
26 |
27 | /*
28 | * @note velocity - determines the speed of the particle, the higher the volicity
29 | * the further it travels on the screen. This is effected by yAcceleration
30 | *
31 | * @note yAcceleration - simulates gravity
32 | * a postive value applys gravity while negative value simulates a
33 | * lack or reduction of gravity allowing particles to "fly".
34 | * the combination of velocity & yAcceleration determines distance
35 | */
36 | cell.velocity = 50
37 | cell.velocityRange = cell.velocity/4
38 | cell.yAcceleration = -150
39 | /*
40 | * @note color will get inherited by the cells in emttierCells array
41 | * @note red/green/blue ranges are the amount by which the color component
42 | * of the cell can vary
43 | * +/- 0.5 for a range between 0 to 1, giving a random color
44 | */
45 | let color = UIColor.init(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0)
46 | cell.color = color.cgColor
47 | cell.redRange = 0.5
48 | cell.greenRange = 0.5
49 | cell.blueRange = 0.5
50 | cell.name = "rocket"
51 | return cell
52 | }
53 |
54 | func makeEmiterCellFlare() -> CAEmitterCell {
55 | let cell = CAEmitterCell()
56 | cell.color = UIColor.white.cgColor
57 | cell.contents = flareImage?.cgImage
58 | /*
59 | * the direction of emission, we need to rotate from the rocket's direction,
60 | * of -pi/2 (upward directions) 180 degrees, so pi radians is 180 degrees
61 | */
62 | cell.emissionLongitude = (2 * .pi)
63 | cell.birthRate = 45
64 | cell.lifetime = 1.5
65 | cell.velocity = 100
66 | cell.scale = 0.3
67 | /*
68 | * simulates gravity, positive gravity pulls the emitter particles down
69 | */
70 | cell.yAcceleration = 350
71 | /*
72 | * 2pi = 360 degress, particles disperse in all directions
73 | */
74 | cell.emissionRange = .pi/7
75 | cell.alphaSpeed = -0.7
76 | cell.scaleSpeed = -0.1
77 | cell.scaleRange = 0.1
78 | cell.beginTime = 0.01
79 | /* needs to be long enough to stay with rocket */
80 | cell.duration = 2.0
81 | cell.name = "flare"
82 | return cell
83 | }
84 |
85 | func makeEmiterCellFirework() -> CAEmitterCell {
86 | let cell = CAEmitterCell()
87 | cell.contents = particleImage?.cgImage
88 | cell.birthRate = 8000
89 | cell.velocity = 130
90 | cell.lifetime = 1.0
91 | cell.emissionRange = (2 * .pi)
92 | /* determines size of explosion */
93 | cell.scale = 0.1
94 | cell.alphaSpeed = -0.2
95 | cell.yAcceleration = 80
96 | cell.beginTime = 1.5
97 | cell.duration = 0.1
98 | cell.scaleSpeed = -0.015
99 | cell.spin = 2
100 | cell.name = "firework"
101 | return cell
102 | }
103 |
104 | /*
105 | * preSpark is an invisible particle used to later emit the sparkle
106 | **/
107 | func makeEmitterCellPrespark(firework:CAEmitterCell) -> CAEmitterCell {
108 | let cell = CAEmitterCell()
109 | cell.birthRate = 80
110 | cell.velocity = firework.velocity * 0.70
111 | cell.lifetime = 1.2
112 | cell.yAcceleration = firework.yAcceleration * 0.85
113 | cell.beginTime = firework.beginTime - 0.2
114 | cell.emissionRange = firework.emissionRange
115 | cell.greenSpeed = 100
116 | cell.blueSpeed = 100
117 | cell.redSpeed = 100
118 | cell.name = "preSpark"
119 | return cell
120 | }
121 |
122 | /* The 'sparkle' at the end of a firework */
123 | func makeSparkle() -> CAEmitterCell {
124 | let cell = CAEmitterCell()
125 | cell.contents = particleImage?.cgImage
126 | cell.birthRate = 10
127 | cell.lifetime = 0.05
128 | cell.yAcceleration = 150
129 | cell.beginTime = 0.8
130 | cell.scale = 0.05
131 | return cell
132 | }
133 |
134 | override func layoutSubviews() {
135 | let emitter = self.layer as! CAEmitterLayer
136 | emitter.emitterPosition = CGPoint(x: bounds.midX, y: bounds.maxY)
137 | emitter.emitterSize = CGSize(width: bounds.size.width * 0.50, height: 1.0)
138 | emitter.renderMode = .additive
139 | let rocket = makeEmiterCellRocket()
140 | let flare = makeEmiterCellFlare()
141 | let firework = makeEmiterCellFirework()
142 | let sparkle = makeSparkle()
143 | let prespark = makeEmitterCellPrespark(firework:firework)
144 | prespark.emitterCells = [sparkle]
145 | rocket.emitterCells = [flare, firework, prespark]
146 | emitter.emitterCells = [rocket]
147 | }
148 |
149 | /*
150 | * Simple firework example
151 | */
152 | // func makeEmiterCell(color:UIColor, velocity:CGFloat, scale:CGFloat)-> CAEmitterCell {
153 | // let cell = CAEmitterCell()
154 | // cell.birthRate = 50
155 | // cell.lifetime = 0.35
156 | // cell.lifetimeRange = 0.75
157 | // cell.emissionRange = 5.0
158 | // /* pi/2 = circle */
159 | // cell.emissionLatitude = .pi/2
160 | // cell.velocity = velocity
161 | // cell.velocityRange = velocity/3
162 | // cell.color = color.cgColor
163 | // cell.scale = 0.3
164 | // cell.contents = particleImage?.cgImage
165 | // return cell
166 | // }
167 |
168 | // override func layoutSubviews() {
169 | // let emitter = self.layer as! CAEmitterLayer
170 | // emitter.emitterShape = .sphere
171 | // emitter.emitterMode = .volume
172 | // emitter.emitterPosition = CGPoint(x: bounds.midX, y: bounds.maxY)
173 | // emitter.emitterSize = CGSize(width: bounds.size.width * 0.40, height: 1.0)
174 | //
175 | //// emitter.emitterShape = .circle
176 | //// emitter.emitterMode = .outline
177 | // emitter.renderMode = .additive
178 | // emitter.emitterPosition = CGPoint(x: bounds.midX, y: bounds.maxY)
179 | // emitter.emitterSize = CGSize(width: 100.0 * 0.25, height: 0)
180 | //
181 | // let red = UIColor(red: 154/255.0, green: 52/255.0, blue: 48/255.0, alpha: 1.0)
182 | // let green = UIColor(red: 126/255.0, green: 204/255.0, blue: 70/255.0, alpha: 1.0)
183 | // let orange = UIColor(red: 212/255.0, green: 134/255.0, blue: 74/255.0, alpha: 1.0)
184 | //
185 | // let em1 = makeEmiterCell(color: red, velocity: 100, scale: 0.3)
186 | // let em2 = makeEmiterCell(color: green, velocity: 100, scale: 0.3)
187 | // let em3 = makeEmiterCell(color: orange, velocity: 200, scale: 0.3)
188 | // emitter.emitterCells = [em1, em2, em3]
189 | // }
190 | }
191 |
--------------------------------------------------------------------------------
/FunWithParticleEmitters.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | CE099E6A2226256400B8A20E /* Smoke.sks in Resources */ = {isa = PBXBuildFile; fileRef = CE099E692226256400B8A20E /* Smoke.sks */; };
11 | CE196FE1223079FE00117313 /* Spark.sks in Resources */ = {isa = PBXBuildFile; fileRef = CE196FE0223079FE00117313 /* Spark.sks */; };
12 | CE4C5AE822207A1F00A4D989 /* ContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4C5AE722207A1F00A4D989 /* ContainerViewController.swift */; };
13 | CE4C5AEA22207A4700A4D989 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4C5AE922207A4700A4D989 /* UIViewController+Extensions.swift */; };
14 | CE4C5AEC22207B2E00A4D989 /* NSLayoutConstraints+Extentsions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4C5AEB22207B2E00A4D989 /* NSLayoutConstraints+Extentsions.swift */; };
15 | CE6CF31E221F83600001E3EA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6CF31D221F83600001E3EA /* AppDelegate.swift */; };
16 | CE6CF323221F83600001E3EA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE6CF321221F83600001E3EA /* Main.storyboard */; };
17 | CE6CF328221F83690001E3EA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE6CF326221F83690001E3EA /* LaunchScreen.storyboard */; };
18 | CE6CF330221F83800001E3EA /* SnowViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6CF32F221F83800001E3EA /* SnowViewController.swift */; };
19 | CE6CF332221F83B90001E3EA /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6CF331221F83B90001E3EA /* GradientView.swift */; };
20 | CE6CF334221F83CD0001E3EA /* SnowParticleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6CF333221F83CD0001E3EA /* SnowParticleView.swift */; };
21 | CE6CF336221F84170001E3EA /* ConfettiParticleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6CF335221F84170001E3EA /* ConfettiParticleView.swift */; };
22 | CE6CF338221F85430001E3EA /* ConfettiViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6CF337221F85430001E3EA /* ConfettiViewController.swift */; };
23 | CE9EA5E52220B76E002D8DA7 /* Rain.sks in Resources */ = {isa = PBXBuildFile; fileRef = CE9EA5E32220B76E002D8DA7 /* Rain.sks */; };
24 | CE9EA5E62220B76E002D8DA7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE9EA5E42220B76E002D8DA7 /* Assets.xcassets */; };
25 | CE9EA5E82220C3CB002D8DA7 /* FireworksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA5E72220C3CB002D8DA7 /* FireworksViewController.swift */; };
26 | CE9EA5EA2220C3F3002D8DA7 /* FireworksParticleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA5E92220C3F3002D8DA7 /* FireworksParticleView.swift */; };
27 | CEE3C6B7223727B6006C8C35 /* Fire.sks in Resources */ = {isa = PBXBuildFile; fileRef = CEE3C6B6223727B6006C8C35 /* Fire.sks */; };
28 | /* End PBXBuildFile section */
29 |
30 | /* Begin PBXFileReference section */
31 | CE099E692226256400B8A20E /* Smoke.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Smoke.sks; sourceTree = ""; };
32 | CE196FE0223079FE00117313 /* Spark.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Spark.sks; sourceTree = ""; };
33 | CE4C5AE722207A1F00A4D989 /* ContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerViewController.swift; sourceTree = ""; };
34 | CE4C5AE922207A4700A4D989 /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extensions.swift"; sourceTree = ""; };
35 | CE4C5AEB22207B2E00A4D989 /* NSLayoutConstraints+Extentsions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSLayoutConstraints+Extentsions.swift"; sourceTree = ""; };
36 | CE6CF31A221F83600001E3EA /* FunWithParticleEmitters.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FunWithParticleEmitters.app; sourceTree = BUILT_PRODUCTS_DIR; };
37 | CE6CF31D221F83600001E3EA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
38 | CE6CF322221F83600001E3EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
39 | CE6CF327221F83690001E3EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
40 | CE6CF329221F83690001E3EA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
41 | CE6CF32F221F83800001E3EA /* SnowViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnowViewController.swift; sourceTree = ""; };
42 | CE6CF331221F83B90001E3EA /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = ""; };
43 | CE6CF333221F83CD0001E3EA /* SnowParticleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnowParticleView.swift; sourceTree = ""; };
44 | CE6CF335221F84170001E3EA /* ConfettiParticleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfettiParticleView.swift; sourceTree = ""; };
45 | CE6CF337221F85430001E3EA /* ConfettiViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfettiViewController.swift; sourceTree = ""; };
46 | CE9EA5E32220B76E002D8DA7 /* Rain.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Rain.sks; sourceTree = ""; };
47 | CE9EA5E42220B76E002D8DA7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ../Assets.xcassets; sourceTree = ""; };
48 | CE9EA5E72220C3CB002D8DA7 /* FireworksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FireworksViewController.swift; sourceTree = ""; };
49 | CE9EA5E92220C3F3002D8DA7 /* FireworksParticleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FireworksParticleView.swift; sourceTree = ""; };
50 | CEE3C6B6223727B6006C8C35 /* Fire.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Fire.sks; sourceTree = ""; };
51 | /* End PBXFileReference section */
52 |
53 | /* Begin PBXFrameworksBuildPhase section */
54 | CE6CF317221F83600001E3EA /* Frameworks */ = {
55 | isa = PBXFrameworksBuildPhase;
56 | buildActionMask = 2147483647;
57 | files = (
58 | );
59 | runOnlyForDeploymentPostprocessing = 0;
60 | };
61 | /* End PBXFrameworksBuildPhase section */
62 |
63 | /* Begin PBXGroup section */
64 | CE6CF311221F83600001E3EA = {
65 | isa = PBXGroup;
66 | children = (
67 | CE6CF31C221F83600001E3EA /* FunWithParticleEmitters */,
68 | CE6CF31B221F83600001E3EA /* Products */,
69 | );
70 | sourceTree = "";
71 | };
72 | CE6CF31B221F83600001E3EA /* Products */ = {
73 | isa = PBXGroup;
74 | children = (
75 | CE6CF31A221F83600001E3EA /* FunWithParticleEmitters.app */,
76 | );
77 | name = Products;
78 | sourceTree = "";
79 | };
80 | CE6CF31C221F83600001E3EA /* FunWithParticleEmitters */ = {
81 | isa = PBXGroup;
82 | children = (
83 | CE6CF31D221F83600001E3EA /* AppDelegate.swift */,
84 | CEFF1C04222853F900DCE9E8 /* View Controllers */,
85 | CEFF1C052228540300DCE9E8 /* Extensions */,
86 | CEFF1C03222853E000DCE9E8 /* Custom Views */,
87 | CE6CF321221F83600001E3EA /* Main.storyboard */,
88 | CE9EA5E42220B76E002D8DA7 /* Assets.xcassets */,
89 | CE6CF326221F83690001E3EA /* LaunchScreen.storyboard */,
90 | CE099E692226256400B8A20E /* Smoke.sks */,
91 | CE9EA5E32220B76E002D8DA7 /* Rain.sks */,
92 | CEE3C6B6223727B6006C8C35 /* Fire.sks */,
93 | CE196FE0223079FE00117313 /* Spark.sks */,
94 | CE6CF329221F83690001E3EA /* Info.plist */,
95 | );
96 | path = FunWithParticleEmitters;
97 | sourceTree = "";
98 | };
99 | CEFF1C03222853E000DCE9E8 /* Custom Views */ = {
100 | isa = PBXGroup;
101 | children = (
102 | CE6CF331221F83B90001E3EA /* GradientView.swift */,
103 | CE9EA5E92220C3F3002D8DA7 /* FireworksParticleView.swift */,
104 | CE6CF333221F83CD0001E3EA /* SnowParticleView.swift */,
105 | CE6CF335221F84170001E3EA /* ConfettiParticleView.swift */,
106 | );
107 | path = "Custom Views";
108 | sourceTree = "";
109 | };
110 | CEFF1C04222853F900DCE9E8 /* View Controllers */ = {
111 | isa = PBXGroup;
112 | children = (
113 | CE4C5AE722207A1F00A4D989 /* ContainerViewController.swift */,
114 | CE6CF32F221F83800001E3EA /* SnowViewController.swift */,
115 | CE9EA5E72220C3CB002D8DA7 /* FireworksViewController.swift */,
116 | CE6CF337221F85430001E3EA /* ConfettiViewController.swift */,
117 | );
118 | path = "View Controllers";
119 | sourceTree = "";
120 | };
121 | CEFF1C052228540300DCE9E8 /* Extensions */ = {
122 | isa = PBXGroup;
123 | children = (
124 | CE4C5AE922207A4700A4D989 /* UIViewController+Extensions.swift */,
125 | CE4C5AEB22207B2E00A4D989 /* NSLayoutConstraints+Extentsions.swift */,
126 | );
127 | path = Extensions;
128 | sourceTree = "";
129 | };
130 | /* End PBXGroup section */
131 |
132 | /* Begin PBXNativeTarget section */
133 | CE6CF319221F83600001E3EA /* FunWithParticleEmitters */ = {
134 | isa = PBXNativeTarget;
135 | buildConfigurationList = CE6CF32C221F83690001E3EA /* Build configuration list for PBXNativeTarget "FunWithParticleEmitters" */;
136 | buildPhases = (
137 | CE6CF316221F83600001E3EA /* Sources */,
138 | CE6CF317221F83600001E3EA /* Frameworks */,
139 | CE6CF318221F83600001E3EA /* Resources */,
140 | );
141 | buildRules = (
142 | );
143 | dependencies = (
144 | );
145 | name = FunWithParticleEmitters;
146 | productName = FunWithParticleEmitters;
147 | productReference = CE6CF31A221F83600001E3EA /* FunWithParticleEmitters.app */;
148 | productType = "com.apple.product-type.application";
149 | };
150 | /* End PBXNativeTarget section */
151 |
152 | /* Begin PBXProject section */
153 | CE6CF312221F83600001E3EA /* Project object */ = {
154 | isa = PBXProject;
155 | attributes = {
156 | LastSwiftUpdateCheck = 1010;
157 | LastUpgradeCheck = 1010;
158 | ORGANIZATIONNAME = user;
159 | TargetAttributes = {
160 | CE6CF319221F83600001E3EA = {
161 | CreatedOnToolsVersion = 10.1;
162 | };
163 | };
164 | };
165 | buildConfigurationList = CE6CF315221F83600001E3EA /* Build configuration list for PBXProject "FunWithParticleEmitters" */;
166 | compatibilityVersion = "Xcode 9.3";
167 | developmentRegion = en;
168 | hasScannedForEncodings = 0;
169 | knownRegions = (
170 | en,
171 | Base,
172 | );
173 | mainGroup = CE6CF311221F83600001E3EA;
174 | productRefGroup = CE6CF31B221F83600001E3EA /* Products */;
175 | projectDirPath = "";
176 | projectRoot = "";
177 | targets = (
178 | CE6CF319221F83600001E3EA /* FunWithParticleEmitters */,
179 | );
180 | };
181 | /* End PBXProject section */
182 |
183 | /* Begin PBXResourcesBuildPhase section */
184 | CE6CF318221F83600001E3EA /* Resources */ = {
185 | isa = PBXResourcesBuildPhase;
186 | buildActionMask = 2147483647;
187 | files = (
188 | CEE3C6B7223727B6006C8C35 /* Fire.sks in Resources */,
189 | CE6CF328221F83690001E3EA /* LaunchScreen.storyboard in Resources */,
190 | CE9EA5E52220B76E002D8DA7 /* Rain.sks in Resources */,
191 | CE6CF323221F83600001E3EA /* Main.storyboard in Resources */,
192 | CE9EA5E62220B76E002D8DA7 /* Assets.xcassets in Resources */,
193 | CE099E6A2226256400B8A20E /* Smoke.sks in Resources */,
194 | CE196FE1223079FE00117313 /* Spark.sks in Resources */,
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | /* End PBXResourcesBuildPhase section */
199 |
200 | /* Begin PBXSourcesBuildPhase section */
201 | CE6CF316221F83600001E3EA /* Sources */ = {
202 | isa = PBXSourcesBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | CE4C5AEC22207B2E00A4D989 /* NSLayoutConstraints+Extentsions.swift in Sources */,
206 | CE6CF31E221F83600001E3EA /* AppDelegate.swift in Sources */,
207 | CE4C5AE822207A1F00A4D989 /* ContainerViewController.swift in Sources */,
208 | CE9EA5EA2220C3F3002D8DA7 /* FireworksParticleView.swift in Sources */,
209 | CE9EA5E82220C3CB002D8DA7 /* FireworksViewController.swift in Sources */,
210 | CE6CF332221F83B90001E3EA /* GradientView.swift in Sources */,
211 | CE4C5AEA22207A4700A4D989 /* UIViewController+Extensions.swift in Sources */,
212 | CE6CF338221F85430001E3EA /* ConfettiViewController.swift in Sources */,
213 | CE6CF334221F83CD0001E3EA /* SnowParticleView.swift in Sources */,
214 | CE6CF336221F84170001E3EA /* ConfettiParticleView.swift in Sources */,
215 | CE6CF330221F83800001E3EA /* SnowViewController.swift in Sources */,
216 | );
217 | runOnlyForDeploymentPostprocessing = 0;
218 | };
219 | /* End PBXSourcesBuildPhase section */
220 |
221 | /* Begin PBXVariantGroup section */
222 | CE6CF321221F83600001E3EA /* Main.storyboard */ = {
223 | isa = PBXVariantGroup;
224 | children = (
225 | CE6CF322221F83600001E3EA /* Base */,
226 | );
227 | name = Main.storyboard;
228 | sourceTree = "";
229 | };
230 | CE6CF326221F83690001E3EA /* LaunchScreen.storyboard */ = {
231 | isa = PBXVariantGroup;
232 | children = (
233 | CE6CF327221F83690001E3EA /* Base */,
234 | );
235 | name = LaunchScreen.storyboard;
236 | sourceTree = "";
237 | };
238 | /* End PBXVariantGroup section */
239 |
240 | /* Begin XCBuildConfiguration section */
241 | CE6CF32A221F83690001E3EA /* Debug */ = {
242 | isa = XCBuildConfiguration;
243 | buildSettings = {
244 | ALWAYS_SEARCH_USER_PATHS = NO;
245 | CLANG_ANALYZER_NONNULL = YES;
246 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
247 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
248 | CLANG_CXX_LIBRARY = "libc++";
249 | CLANG_ENABLE_MODULES = YES;
250 | CLANG_ENABLE_OBJC_ARC = YES;
251 | CLANG_ENABLE_OBJC_WEAK = YES;
252 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
253 | CLANG_WARN_BOOL_CONVERSION = YES;
254 | CLANG_WARN_COMMA = YES;
255 | CLANG_WARN_CONSTANT_CONVERSION = YES;
256 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
257 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
258 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
259 | CLANG_WARN_EMPTY_BODY = YES;
260 | CLANG_WARN_ENUM_CONVERSION = YES;
261 | CLANG_WARN_INFINITE_RECURSION = YES;
262 | CLANG_WARN_INT_CONVERSION = YES;
263 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
264 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
265 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
266 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
267 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
268 | CLANG_WARN_STRICT_PROTOTYPES = YES;
269 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
270 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
271 | CLANG_WARN_UNREACHABLE_CODE = YES;
272 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
273 | CODE_SIGN_IDENTITY = "iPhone Developer";
274 | COPY_PHASE_STRIP = NO;
275 | DEBUG_INFORMATION_FORMAT = dwarf;
276 | ENABLE_STRICT_OBJC_MSGSEND = YES;
277 | ENABLE_TESTABILITY = YES;
278 | GCC_C_LANGUAGE_STANDARD = gnu11;
279 | GCC_DYNAMIC_NO_PIC = NO;
280 | GCC_NO_COMMON_BLOCKS = YES;
281 | GCC_OPTIMIZATION_LEVEL = 0;
282 | GCC_PREPROCESSOR_DEFINITIONS = (
283 | "DEBUG=1",
284 | "$(inherited)",
285 | );
286 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
287 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
288 | GCC_WARN_UNDECLARED_SELECTOR = YES;
289 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
290 | GCC_WARN_UNUSED_FUNCTION = YES;
291 | GCC_WARN_UNUSED_VARIABLE = YES;
292 | IPHONEOS_DEPLOYMENT_TARGET = 12.1;
293 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
294 | MTL_FAST_MATH = YES;
295 | ONLY_ACTIVE_ARCH = YES;
296 | SDKROOT = iphoneos;
297 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
298 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
299 | };
300 | name = Debug;
301 | };
302 | CE6CF32B221F83690001E3EA /* Release */ = {
303 | isa = XCBuildConfiguration;
304 | buildSettings = {
305 | ALWAYS_SEARCH_USER_PATHS = NO;
306 | CLANG_ANALYZER_NONNULL = YES;
307 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
308 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
309 | CLANG_CXX_LIBRARY = "libc++";
310 | CLANG_ENABLE_MODULES = YES;
311 | CLANG_ENABLE_OBJC_ARC = YES;
312 | CLANG_ENABLE_OBJC_WEAK = YES;
313 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
314 | CLANG_WARN_BOOL_CONVERSION = YES;
315 | CLANG_WARN_COMMA = YES;
316 | CLANG_WARN_CONSTANT_CONVERSION = YES;
317 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
318 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
319 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
320 | CLANG_WARN_EMPTY_BODY = YES;
321 | CLANG_WARN_ENUM_CONVERSION = YES;
322 | CLANG_WARN_INFINITE_RECURSION = YES;
323 | CLANG_WARN_INT_CONVERSION = YES;
324 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
325 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
326 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
328 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
329 | CLANG_WARN_STRICT_PROTOTYPES = YES;
330 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
331 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
332 | CLANG_WARN_UNREACHABLE_CODE = YES;
333 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
334 | CODE_SIGN_IDENTITY = "iPhone Developer";
335 | COPY_PHASE_STRIP = NO;
336 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
337 | ENABLE_NS_ASSERTIONS = NO;
338 | ENABLE_STRICT_OBJC_MSGSEND = YES;
339 | GCC_C_LANGUAGE_STANDARD = gnu11;
340 | GCC_NO_COMMON_BLOCKS = YES;
341 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
342 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
343 | GCC_WARN_UNDECLARED_SELECTOR = YES;
344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
345 | GCC_WARN_UNUSED_FUNCTION = YES;
346 | GCC_WARN_UNUSED_VARIABLE = YES;
347 | IPHONEOS_DEPLOYMENT_TARGET = 12.1;
348 | MTL_ENABLE_DEBUG_INFO = NO;
349 | MTL_FAST_MATH = YES;
350 | SDKROOT = iphoneos;
351 | SWIFT_COMPILATION_MODE = wholemodule;
352 | SWIFT_OPTIMIZATION_LEVEL = "-O";
353 | VALIDATE_PRODUCT = YES;
354 | };
355 | name = Release;
356 | };
357 | CE6CF32D221F83690001E3EA /* Debug */ = {
358 | isa = XCBuildConfiguration;
359 | buildSettings = {
360 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
361 | CODE_SIGN_STYLE = Automatic;
362 | DEVELOPMENT_TEAM = S264RF7436;
363 | INFOPLIST_FILE = FunWithParticleEmitters/Info.plist;
364 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
365 | LD_RUNPATH_SEARCH_PATHS = (
366 | "$(inherited)",
367 | "@executable_path/Frameworks",
368 | );
369 | PRODUCT_BUNDLE_IDENTIFIER = com.example.FunWithParticleEmitters;
370 | PRODUCT_NAME = "$(TARGET_NAME)";
371 | SWIFT_VERSION = 5.0;
372 | TARGETED_DEVICE_FAMILY = "1,2";
373 | };
374 | name = Debug;
375 | };
376 | CE6CF32E221F83690001E3EA /* Release */ = {
377 | isa = XCBuildConfiguration;
378 | buildSettings = {
379 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
380 | CODE_SIGN_STYLE = Automatic;
381 | DEVELOPMENT_TEAM = S264RF7436;
382 | INFOPLIST_FILE = FunWithParticleEmitters/Info.plist;
383 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
384 | LD_RUNPATH_SEARCH_PATHS = (
385 | "$(inherited)",
386 | "@executable_path/Frameworks",
387 | );
388 | PRODUCT_BUNDLE_IDENTIFIER = com.example.FunWithParticleEmitters;
389 | PRODUCT_NAME = "$(TARGET_NAME)";
390 | SWIFT_VERSION = 5.0;
391 | TARGETED_DEVICE_FAMILY = "1,2";
392 | };
393 | name = Release;
394 | };
395 | /* End XCBuildConfiguration section */
396 |
397 | /* Begin XCConfigurationList section */
398 | CE6CF315221F83600001E3EA /* Build configuration list for PBXProject "FunWithParticleEmitters" */ = {
399 | isa = XCConfigurationList;
400 | buildConfigurations = (
401 | CE6CF32A221F83690001E3EA /* Debug */,
402 | CE6CF32B221F83690001E3EA /* Release */,
403 | );
404 | defaultConfigurationIsVisible = 0;
405 | defaultConfigurationName = Release;
406 | };
407 | CE6CF32C221F83690001E3EA /* Build configuration list for PBXNativeTarget "FunWithParticleEmitters" */ = {
408 | isa = XCConfigurationList;
409 | buildConfigurations = (
410 | CE6CF32D221F83690001E3EA /* Debug */,
411 | CE6CF32E221F83690001E3EA /* Release */,
412 | );
413 | defaultConfigurationIsVisible = 0;
414 | defaultConfigurationName = Release;
415 | };
416 | /* End XCConfigurationList section */
417 | };
418 | rootObject = CE6CF312221F83600001E3EA /* Project object */;
419 | }
420 |
--------------------------------------------------------------------------------