Skip to content

Instantly share code, notes, and snippets.

View juanarzola's full-sized avatar

Juan Arzola juanarzola

View GitHub Profile
@juanarzola
juanarzola / EnvironmentDimmedTintColorViewModifier.swift
Created March 17, 2025 21:03
Exposes tintColor in the dimmed state to SwiftUI. Use this to adapt any non-accentColor color to the dimmed state.
//
// EnvironmentDimmedTintColorViewModifier.swift
// Learn
//
// Created by Juan Arzola on 3/17/25.
// Copyright © 2025 Juan Arzola. All rights reserved.
//
import SwiftUI
import UIKit
@juanarzola
juanarzola / KeyboardShortcutButtons.swift
Last active March 17, 2025 21:11
Overlay with buttons used just for triggering keyboard shortcuts
//
// KeyboardShortcutButtons.swift
// Learn
//
// Created by Juan Arzola on 3/15/25.
// Copyright © 2025 Juan Arzola. All rights reserved.
//
import SwiftUI
import UIKit
@juanarzola
juanarzola / PersistentIdentifier+shortDescription.swift
Created December 19, 2024 09:45
A super simple hack to get a short description of SwiftData's PersistentIdentifier suitable for debugging. Format: `{ModelName}/p{Number}`
import SwiftData
extension PersistentIdentifier {
var shortDebugDescription: String {
let description = "\(self)"
let entityNameRange = description.firstMatch(of: self.entityName)?.range
let lastParenthesisRange = description.firstMatch(of: ")")?.range
if let entityNameRange, let lastParenthesisRange,
entityNameRange.lowerBound < lastParenthesisRange.upperBound {
return String(description[entityNameRange.lowerBound..<lastParenthesisRange.lowerBound])
@juanarzola
juanarzola / ModelContainer+runNonisolated.swift
Last active August 20, 2024 23:37
Convenience extension for running ModelActor code in the background
extension ModelContainer {
// non-throwing version
nonisolated func runNonisolated<ResultType, ActorType: InitWithModelContainer>(
action: @Sendable (_ actor: ActorType) async -> ResultType
) async -> ResultType {
let actor = ActorType(modelContainer: self)
let result = await action(actor)
return result
}
// throwing version
@juanarzola
juanarzola / swift-data-request.swift
Last active June 18, 2024 06:17
Proposed query API for SwiftData notifications (stream based)
// Our one super simple SwiftData Model
@Model
class Item {
...
}
// MARK: - TodayView
@MainActor
@juanarzola
juanarzola / updateLoop.swift
Last active June 8, 2024 17:31
ViewModel (or controller(!)) updateLoop pattern that keeps the model up-to-date in a task.
// MARK: - TodayView
@MainActor
struct TodayView: View {
@State private var viewModel = TodayViewModel()
@Environment(\.modelContext) private var modelContext
var body: some View {
HStack {
switch viewModel.content {
@juanarzola
juanarzola / SelectedBackgroundColorHackery.swift
Last active June 5, 2024 18:20
Workaround for lack of `listRowSelectedBackground` or some way of defining an adaptive background style with your own color
struct ContentView: View {
var body: some View {
List {
SomeRow()
// set the background of the row
.listRowBackground(ListRowBackground())
// .listRowSelectedBackground(ListRowSelectedBackground())
// Oh no, `listRowSelectedBackground` above is not a real API, so list cells don't highlight when selected anymore.
// What do we do now?
@juanarzola
juanarzola / SectionBuilderSample.swift
Last active June 5, 2024 18:21
An attempt to reduce unnecessary computations for section building in the body of a View. Ultimately I had to modify it (See comments)
// slow version
struct MyFancyList: View {
@Query(FetchDescriptors.fancyListItems) var items
var sections: [ListSection] = []
var body: some View {
// it's a bad idea to build sections here, as that can execute for all sorts of updates to the view (there's more going on in this view in the original code)
SomethingRenderingSections(ListSection.sections(for: items, editMode: editMode, searchText: searchText)
.fullScreenCover(isPresented: $someFullScreenThingVisible) { SomethingThatCovers() }
@juanarzola
juanarzola / Ents.lua
Last active June 5, 2024 18:22
For ScriptExtender with Baldur's Gate 3: Output all Entities that match a component name and display name (empty string matches all)
-- _Ents: Filters current entities in the engine, matching their component names and/or display names.
--
-- @param pattern: filter by entities with component names matching pattern. Empty string "" matches all.
-- @param displayNamePattern: filter by entities with displayName (where displayName is a heuristic determined
-- from various components) matching `displayNamePattern`. Empty string "" matches all.
-- @param withComponents: include component names in the output result
--
_Ents = function(pattern, displayNamePattern, withComponents)
local entities = Ext.Entity.GetAllEntities()
local result = {}
@juanarzola
juanarzola / ChangeType.cs
Last active October 6, 2016 08:44
UniRx observable wrappers for Entitas entity and group events
using System;
namespace Entitas {
/** Used in the *AnyChangeObservable methods to observe multiple change types */
[Flags]
public enum ChangeType : short{
Addition = 1 << 0,
Replacement = 1 << 1,
Removal = 1 << 2,