Categories
AI SwiftUI

ChatGPT SwiftUI Christmas Tree 2023

Revisiting last year’s challenge, let’s see how this year goes with GPT-4.

I used the same prompt from 2022:

Draw a Christmas tree using SwiftUI

Interestingly this time it included the Triangle type and it was almost line-for-line the exact one I substituted in last year.

import SwiftUI

struct ContentView: View {
    var body: some View {
        ZStack {
            // Background
            Color.white.edgesIgnoringSafeArea(.all)

            // Christmas Tree
            VStack {
                ForEach((1...5).reversed(), id: \.self) { i in
                    TreeLayer(width: CGFloat(i) * 60)
                }
                Rectangle()
                    .frame(width: 40, height: 50)
                    .foregroundColor(.brown)
            }
        }
    }
}

struct TreeLayer: View {
    var width: CGFloat

    var body: some View {
        ZStack {
            Triangle()
                .fill(Color.green)
                .frame(width: width, height: width * 0.75)
            // Add decorations here
        }
    }
}

struct Triangle: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.move(to: CGPoint(x: rect.midX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        path.closeSubpath()
        return path
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

And here’s the output for 2022 and 2023! 🎄😀

Categories
AI SwiftUI

Can ChatGPT draw a Christmas tree in SwiftUI?

Here’s the prompt I gave ChatGPT:

Draw a Christmas tree using SwiftUI

Here’s the code I got:

struct ChristmasTree: View {
    var body: some View {
        ZStack {
            // draw the tree trunk
            Rectangle()
                .fill(Color.brown)
                .frame(width: 20, height: 100)

            // draw the tree branches
            ForEach(0..<5) { i in
                HStack(spacing: 5) {
                    ForEach(0..<5-i) { j in
                        Triangle()
                            .fill(Color.green)
                            .frame(width: 10, height: 10)
                    }
                }
                .offset(x: 0, y: -10 * CGFloat(i))
            }

            // draw the star on top of the tree
            Circle()
                .fill(Color.yellow)
                .frame(width: 10, height: 10)
                .offset(x: 0, y: -50)
        }
    }
}

The only major issue syntax-wise is that Triangle() isn’t defined – where did it get that?

A quick visit to Hacking with Swift had this nice snippet, which I dropped in.

struct Triangle: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()

        path.move(to: CGPoint(x: rect.midX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.midX, y: rect.minY))

        return path
    }
}

Now we can compile and…. tada!

A Christmas tree in SwiftUI drawn by ChatGPT

Not great, but darn impressive! 🎄🤯

Categories
Arduino Fun iOS SwiftUI

NeoPixel tree progress

This weekend the NeoPixel tree got many much-needed updates!

Though I have more ideas to implement, the basics of what I wanted to do are complete, like sending commands remotely.

What we can currently do:

  • Set the brightness
  • Change the color
  • Turn the pixels off
  • Run some built-in sequences, like a nice rainbow
  • Set repeating color patterns
  • Set individual pixels

I also threw together a really quick iOS app to set the color with SwiftUI’s built-in ColorPicker view. Thanks to the Rover project (another one that’s been neglected), I had some UDP client code I could borrow to speed up development.

Changing the color of the tree with a SwiftUI ColorPicker view.
Categories
Swift SwiftUI

Squishy buttons!

Categories
Swift SwiftUI

Faux Notch Fun

I’ve seen a lot of these little “fake notch” apps pop up since Apple’s new MacBooks were announced, but I didn’t see a lot of source code – so of course I was nerd sniped.

Here’s a basic example of making one using AppKit and SwiftUI!

Categories
iOS Projects Swift SwiftUI

Wyze Cam in iOS

Categories
Arduino Coding iOS Projects Swift SwiftUI

Flip Dots!

I saw flip dots (also called flip discs) last year for the first time and instantly knew I needed some in my life. If you’re not familiar with them, check out how they work!

The particular model I have is the ALFAZETA XY5, which may be the easiest way to get up and running, but certainly not the least expensive.

After getting the board, all you need is:

  1. 24V power supply
  2. Something that talks over RS485 (in my case I used an ESP8266 connected to a MAX3485 board)
  3. Their documentation that defines the controller data protocol

I plan to write in more detail how it all works, but for this demo the stack is:

  1. SwiftUI app that runs SwiftGFXWrapper (which is mainly Adafruit’s GFX Library under the hood)
  2. The app sends the entire pixel buffer over UDP to the ESP8266
  3. The ESP8266 sends data to the XY5 over RS485 using their controller’s protocol

Update: Here’s more info on how it all works!

Categories
Projects Swift SwiftUI

Playground support for SwiftGFXWrapper

For even easier prototyping, I’ve added Swift Playground support to my SwiftGFXWrapper project!

Categories
Projects Swift SwiftUI

Adafruit GFX -> Swift

Another fun project from a few weekends ago: Wrapping the Adafruit GFX in Objective C and bridging to Swift for some neat 8-bit effects!

The most interesting component of this project so far has been building a Swift closure that is executed in C as a const void *. This was new territory for me and a lot of fun to figure out!

This (work in progress) repo has been open sourced!

Categories
SwiftUI

SwiftUI for rapid prototypes

SwiftUI is turning into my go-to for rapid prototyping. Here’s an example of a light / dark mode switcher that I think would work well on web…

See the code here!