Christmas Special



Happy Holidays!
It's now Boxing Day 2023, and in between prepping the turkey n tahteeers, I've thrown together a little Christmassy Swift Joy.
I've created a Christmas tree which lights up upon pressing the Merry Christmas button. Initially I've tried to play around with the new animated SF Symbols but I boiled it down to some plain and simple ForEach structure in SwiftUI.
I've played around with the size of the SF Symbol, to figure out how many rows I can get away with, making me land on 8. So I went ahead and created the following:
```
ForEach(0..<8, id: \.self) { row in
HStack {
ForEach(0..<(row + 2), id: \.self) { item in
BaubleView(animationsRunning: $animationsRunning, availableColors: availableColors)
}
}
}
```
Here's the full code:
import SwiftUI
structContentView: View {
@StateprivatevaranimationsRunning = false
@StateprivatevaranimationCount = 0
// Array to hold colors for each circle
let availableColors: [Color] = [.red, .green, .blue, .orange, .purple]
var body: some View {
// This is the start of the tree V Stack
VStack {
// Star
VStack{
Image(systemName: "star.fill")
}
.font(.largeTitle)
.symbolEffect(.bounce, value: animationsRunning)
.foregroundColor(.yellow)
// BaubleView with ForEach
ForEach(0..<8, id: \.self) { row in
HStack {
ForEach(0..<(row + 2), id: \.self) { item in
BaubleView(animationsRunning: $animationsRunning, availableColors: availableColors)
}
}
}
// Tree Trunk
VStack {
Image(systemName: "rectangle.portrait.fill")
.font(.system(size: 48))
.foregroundColor(.brown)
}
}
Button("Merry Christmas") {
withAnimation {
animationsRunning.toggle()
}
}
.frame(width: 255, height: 50)
.fontWeight(.semibold)
.foregroundColor(.white)
.background(.red)
.cornerRadius(12.0)
.padding()
}
}
structBaubleView: View {
@BindingvaranimationsRunning: Bool
letavailableColors: [Color]
@StateprivatevarisFilled = false
@State private var color: Color = .green
var body: some View {
Image(systemName: isFilled ? "circle.fill" : "circle")
.font(.title)
.foregroundColor(color)
.onReceive(Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()) { _ in
if animationsRunning {
isFilled.toggle()
color = availableColors.randomElement() ?? .green
}
}
}
}
#Preview {
ContentView()
.preferredColorScheme(.dark)
}

