Skip to content

Instantly share code, notes, and snippets.

View ryanlintott's full-sized avatar

Ryan Lintott ryanlintott

View GitHub Profile
@ryanlintott
ryanlintott / ScareSheetView.swift
Created May 8, 2025 18:56
A silly scare sheet that looks like a ghost.
//
// ShareSheetView.swift
// ScareSheet
//
// Created by Ryan Lintott on 2025-05-08.
//
import ShapeUp
import SwiftUI
@ryanlintott
ryanlintott / WidgetConfiguration+extensions.swift
Last active May 5, 2025 19:59
Extensions for WidgetConfiguration that make it easier to add disfavoredLocations and promptsForUserConfiguration while supporting older versions of iOS.
//
// WidgetConfiguration+extensions.swift
//
//
// Created by Ryan Lintott on 2023-09-11.
//
import SwiftUI
import WidgetKit
@ryanlintott
ryanlintott / OnPreferenceChangeError.md
Last active April 16, 2025 07:01
FB15989990 - A Sendable onPreferenceChange closure cannot change main actor view properties in Xcode 16.2 beta 3. This has been fixed in Xcode 16.3.

In XCode 16.2 beta 3 the onPreferenceChange view modifier closure was changed to be @Sendable. This change caused a number of errors in my code when I try to use the value in the closure to update a view property.

I’ve attached a simple WidthReader example that shows these errors.

This change seems similar to the recent change to the alignmentGuide closure. The difference is the alignmentGuide closure is used to change the value of the alignment guide and I have no expectation of using it to update view properties. The onPreferenceChange closure returns no value and as far as I can figure the only use of it would be to modify view properties.

As a workaround I could wrap each modification in a main actor Task but I’m concerned about this somehow delaying my updates and causing visual glitches in the UI.

Ideally I would like the onPreferenceChange modifier to be annotated with @MainActor instead of @Sendable as I can’t see a use case when someone would use the value to update something off the main thread.

@ryanlintott
ryanlintott / ContentView.swift
Last active April 13, 2025 19:10
A SwiftUI environment value for the keyboard height that updates with animation. This is useful when you want a specific view in a stack to stick to the bottom of the keyboard when the keyboard moves up. Now included in FrameUp https://github.com/ryanlintott/FrameUp
import SwiftUI
struct ContentView: View {
var body: some View {
KeyboardAvoidingWithOffset()
.keyboardHeightEnvironmentValue()
}
}
struct KeyboardAvoidingWithOffset: View {
@ryanlintott
ryanlintott / View+ifAvailable.swift
Last active April 3, 2025 17:46
A conditional SwiftUI view extension that can be used to optionally apply view modifiers based on OS availability. Learn more about how it works here: https://youtu.be/mgplcrJh0K0?si=YNz0IVSiN-3myb08
import SwiftUI
extension View {
/// Applies the given transform or returns the untransformed view.
///
/// Useful for availability branching on view modifiers. Do not branch with any properties that may change during runtime as this will cause errors.
/// - Parameters:
/// - transform: The transform to apply to the source `View`.
/// - Returns: The view transformed by the transform.
@ViewBuilder
@ryanlintott
ryanlintott / JustifiedTextExample2.swift
Last active January 27, 2025 14:23
A way to justify text using a single SwiftUI Text view.
//
// JustifiedTextExample2.swift
// FrameUpExample
//
// Created by Ryan Lintott on 2022-11-15.
//
import SwiftUI
import WidgetKit
@ryanlintott
ryanlintott / CustomColorScheme.swift
Last active November 29, 2024 15:53
Custom color scheme view modifier for SwiftUI. Sets the color scheme to light mode, dark mode, or matches the system. If set to match, the app will respond to system-wide color scheme changes properly. A simple widget color scheme implementation is also provided.
import SwiftUI
enum CustomColorScheme: Int, CaseIterable, Identifiable, Codable {
static var defaultKey = "customColorScheme"
static var defaultValue = CustomColorScheme.system
case system = 0
case light = 1
case dark = 2
@ryanlintott
ryanlintott / AlignmentGuideForEachCrash.swift
Last active October 18, 2024 17:10
FB15126597: AlignmentGuide crash when animating a Shape property. If an alignmentGuide affects the layout of a Shape with an animated property, changes to that property cause the app to crash. This crash occurs in Xcode 16 RC1 only when running in Swift 6 language mode.
struct CrashingView: View {
@State private var items: [String] = Array(1...10).map { String("\($0)") }
var body: some View {
VStack {
HStack {
ForEach(items, id: \.self) { item in
Text(item)
/// Adding @Sendable to the closure fixes the crash
.alignmentGuide(HorizontalAlignment.center) { @Sendable d in
@ryanlintott
ryanlintott / NoClipText.swift
Last active October 1, 2024 18:25
Alternative Text view for SwiftUI with an extendable clipping area. This is a fix for certain fonts and characters that have a clipped intrinsic size.
import SwiftUI
import UIKit
struct NoClipText: UIViewRepresentable {
typealias UIViewType = NoClipLabel
let text: String
let font: UIFont
let clipExtension: EdgeSizes
@ryanlintott
ryanlintott / CrashingView.swift
Last active September 15, 2024 02:05
FB14810097: App crashes when an item with an alignmentGuide is removed from ForEach inside a Layout with animation.
//
// CrashingView.swift
// CrashRemovingItem
//
// Created by Ryan Lintott on 2024-08-13.
//
import SwiftUI
struct CrashingView: View {