Skip to content

Instantly share code, notes, and snippets.

func store<T: Codable>(values: [String: T]) {
// How do I check if *this* if nil?
let myVal = values["hello"]
print(myVal) // Optional(nil)
print(myVal == nil) // false
}
let point1: CGPoint? = nil
store(values: ["hello": point1])
struct MyWrapper {
let key: String
let value: any Codable
}
let point: CGPoint? = nil
let wrapper = MyWrapper(key: "point", value: point)
// ⚠️ Comparing non-optional type always returns false
// … but it IS nil :(
@christianselig
christianselig / ObservableCatWorld.swift
Created October 7, 2024 13:23
Attempting to observe pesky disk cats in SwiftUI
import SwiftUI
struct ContentView: View {
@State var catWorld = CatWorld.shared
var body: some View {
VStack {
Text("Value: \(catWorld.giveCat() ?? "No cat yet")")
Text("num: \(catWorld.number)")
@christianselig
christianselig / widgets.swift
Created September 18, 2024 19:23
Proper way to handle backwards compatibility of iOS widgets
import WidgetKit
import SwiftUI
@main
struct WidgetExtMain {
static func main() {
if #available(iOS 18.0, *) {
MyWidgets_18.main()
} else {
@christianselig
christianselig / hammerspoon.lua
Created August 28, 2024 17:08
Add middle-button panning support to Sketch to match Figma, Fusion 360, etc.
-- Make Sketch use the middle mouse button for dragging like Figma, Fusion 360, etc.
local middleMouseDown = false
-- Function to handle the middle mouse down event
local function middleMouseDownHandler(event)
if event:getType() == hs.eventtap.event.types.otherMouseDown then
if event:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber']) == 2 then
middleMouseDown = true
-- Simulate holding down the space bar
hs.eventtap.event.newKeyEvent(hs.keycodes.map['space'], true):post()
@christianselig
christianselig / LongPressButton.swift
Last active November 4, 2024 06:52
How to accomplish a long-pressable button in SwiftUI with two different techniques. The first just uses SwiftUI but due to the simultaneous gesture requirement you also have to ensure both don't fire concurrently. The second uses UIKit and wraps UIButton and UILongPressGestureRecognizer which natively handles this behavior.
import SwiftUI
// PURE SwiftUI way with State tracking to prevent double events
struct ContentView: View {
@State private var ignoreTapEvent = false
var body: some View {
Button {
guard !ignoreTapEvent else {
import SwiftUI
import WebKit
@main
struct WebViewActingUpApp: App {
var body: some Scene {
WindowGroup(id: "Main") {
ContentView()
}
import SwiftUI
import WebKit
@main
struct WebViewActingUpApp: App {
var body: some Scene {
WindowGroup(id: "Main") {
ContentView()
}
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
Text("Welcome to my ice cream store")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItemGroup(placement: .topBarLeading) {
Button {
import SwiftUI
@main
struct WindowPresentationFunApp: App {
@State var appState = AppState()
var body: some Scene {
WindowGroup {
RootView(appState: appState)
.onAppear {