Skip to content

Instantly share code, notes, and snippets.

View ryanlintott's full-sized avatar

Ryan Lintott ryanlintott

View GitHub Profile
@ryanlintott
ryanlintott / OnPreferenceChangeError.md
Last active January 13, 2025 09:31
FB15989990 - A Sendable onPreferenceChange closure cannot change main actor view properties in XCode 16.2 beta 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 / 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 / ModelContext+extension.swift
Last active September 10, 2024 17:24
A fetch method that uses a parameter pack to fetch one or more PersistentModel types then runs a closure to return a Sendable result.
import SwiftData
extension ModelContext {
/// FetchDescriptor is Sendable but inside a parameter pack there are sometimes issues with this working in Swift 6.0
func fetch<each T: PersistentModel, Result: Sendable>(
_ descriptor: repeat FetchDescriptor<each T>,
with closure: @escaping @Sendable (repeat [each T]) throws -> Result
) throws -> Result {
try closure(repeat try fetch(each descriptor))
}
@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 {
@ryanlintott
ryanlintott / CrashingView.swift
Last active August 15, 2024 12:45
FB14787915: VariadicView crashes when an item is removed if the child view has an alignmentGuide and the change is animated.
//
// CrashingView.swift
// CrashRemovingItem
//
// Created by Ryan Lintott on 2024-08-13.
//
import SwiftUI
fileprivate struct _VariadicRoot: _VariadicView_MultiViewRoot {
@ryanlintott
ryanlintott / NoClipTextRenderer.swift
Last active July 9, 2024 01:29
SwiftUI may be clipping your Text views but TextRenderer in iOS 18 might let you fix it in a far less hacky way. Hacky methods that support older OS versions can be found here: https://github.com/ryanlintott/Unicodices
//
// NoClipTextRenderer.swift
//
//
// Created by Ryan Lintott on 2024-07-08.
//
import SwiftUI
@available(iOS 18, *)
@ryanlintott
ryanlintott / AutoLayoutTestApp.swift
Last active March 8, 2024 04:33
A SwiftUI example of an alert window that would be easy to implement using AutoLayout. This implementation uses onSizeChange from FrameUp https://github.com/ryanlintott/FrameUp
//
// AutoLayoutTestApp.swift
// AutoLayoutTest
//
// Created by Ryan Lintott on 2024-03-07.
//
import FrameUp
import SwiftUI
@ryanlintott
ryanlintott / ShrinkingLabel.swift
Last active February 21, 2024 18:31
An example of a label that grows and shrinks in overall size and frame height. Requires FrameUp https://github.com/ryanlintott/FrameUp
//
// ShrinkingLabel.swift
// FrameUpExample
//
// Created by Ryan Lintott on 2024-02-21.
//
import FrameUp
import SwiftUI
@ryanlintott
ryanlintott / KeyboardButtonStyle.swift
Last active February 25, 2024 01:15
A SwiftUI ButtonStyle that looks like an iOS keyboard key.
//
// KeyboardButtonStyle.swift
// Wordhord
//
// Created by Ryan Lintott on 2024-02-06.
//
import ShapeUp
import SwiftUI
@ryanlintott
ryanlintott / ThemeListSelection.swift
Created February 12, 2024 20:54
A SwiftUI List where a single item is selected across Sections.
import SwiftUI
struct Theme: Identifiable {
let id: UUID
let name: String
}
extension Theme {
static let blue = Self(id: UUID(), name: "Blue")
static let red = Self(id: UUID(), name: "Red")