Collect findings from other people's writing, with sources

The skill so far only held what we broke ourselves. Most of what is worth
knowing about a new SDK is found rather than suffered — release notes,
other people's articles — and that deserves a place too, on terms that
stay fair to whoever wrote it.

So: entries in our own words, source named and linked, and the one thing
no external article can supply — what it would replace in our code and
whether it is genuinely a step forward. Attribution answers plagiarism,
not copyright, so nothing is pasted; an API signature is a fact, the
paragraph explaining it is not ours to take.

First four entries come from Natalia Panferova's writing at nilcoalescing
.com: the close button role and concentric corners, both of which replace
things we hand-built; ScrollPosition, which replaces one wrapper view;
and the iOS 27 toolbar APIs, which we cannot use at our deployment target
but which would delete a workaround the day we can.

A LICENSE was overdue and now says plainly what is ours, what is Apple's
and stays out of the repository, and what belongs to the authors we cite.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
TomUviandClaude Opus 5 committed 2026-08-16 23:14:51 +02:00
1 parent 905ad2ce3e
commit f84852d49c
8 files changed
+257 -9

No files matched your search

@@ -0,0 +1,39 @@
---
name: apple-findings
description: A curated file of Apple platform APIs worth adopting, each with where we found it and what it would replace in our code — iOS 26 UI affordances (close button role, concentric corners), modern scrolling APIs, and things noted for a later deployment target. Use when reviewing SwiftUI code for outdated patterns, when a hand-built control might have a system equivalent, or when deciding whether a newly published API is worth adopting.
---
# Findings
Things worth adopting that we found elsewhere — release notes, other
people's writing, conference talks — written up in our own words with the
source named, and with the part nobody else can write for us: what it
would replace in our code and whether it is actually a step forward.
Read `references/` for the individual entries.
| File | Covers |
|---|---|
| `references/ios26-ui.md` | `Button(role: .close)`, concentric corners |
| `references/scrolling.md` | `ScrollPosition` and friends |
| `references/waiting-on-target.md` | Known, not yet usable at our deployment target |
## How to add an entry
**Write it yourself.** Do not paste someone else's prose or their longer
code examples. An API signature is a fact and facts are free; a paragraph
explaining it is their work. Name the source and link it — that is
courtesy and it lets the next person check whether the entry has aged.
Every entry answers four things:
1. **What it is** — the API, in one or two sentences.
2. **What it replaces** — the hand-built thing in our code, with the file
if we know it. An entry without this is a bookmark, not a finding.
3. **Whether it is a step forward** — sometimes the honest answer is "no,
ours is fine", and that is worth recording so nobody re-litigates it.
4. **Source** — author, title, link, date read.
If an entry turns out to be wrong or the API changes, fix it in place and
say so. A stale finding is worse than no finding, because it is quoted
with confidence.
@@ -0,0 +1,61 @@
# iOS 26 UI affordances
## `Button(role: .close)`
**What it is.** A button role that renders the platform's standard close
control — an `xmark`, positioned and labelled by the system — without
supplying a label or icon. Distinct from `.cancel`, which implies
discarding work; `.close` is for dismissing something informational.
```swift
.toolbar {
Button(role: .close) { dismiss() }
}
```
**What it replaces.** Every hand-assembled close button: an
`Image(systemName: "xmark.circle.fill")` with a hierarchical rendering
mode, a colour chosen to sit on the background, `.buttonStyle(.plain)`,
and a manual `accessibilityLabel("Close")`. We had two of those in one
file alone.
**Step forward?** Yes, unambiguously. Correct placement per platform,
VoiceOver label and its localisation come from the system, and two
hand-written strings leave the catalogue. Roughly six lines become one.
**Source.** Natalia Panferova, "Add a Close button to SwiftUI modals on
iOS 26", nilcoalescing.com, 20 Oct 2025. Read 16 Aug 2026.
## Concentric corners
**What it is.** Nested rounded rectangles whose inner and outer corner
arcs share a centre, so the gap between them stays even the whole way
round. `ConcentricRectangle` is the shape; `containerShape(.rect(cornerRadius:))`
tells nested views what they are sitting inside so they can derive their
own radius. `isUniform: true` forces all four corners equal, and a
`minimum:` guarantees a floor when the inner shape sits far from the edge.
```swift
ZStack {
ConcentricRectangle().fill(.thickMaterial)
ConcentricRectangle(corners: .concentric, isUniform: true)
.fill(Color.blue.gradient)
}
.containerShape(.rect(cornerRadius: 24))
```
**What it replaces.** Hand-guessed radii for nested panels. In our card
app: a white "ticket" at radius 16 inside a coloured panel at 24, another
pair at 22 inside 22, tiles at 12 inside 20. Those numbers were picked by
eye at one size and drift apart at any other.
**Step forward?** Yes, and it is the kind that shows. The Wallet-pass look
we are copying is built on exactly this relationship, and doing it by hand
means re-tuning every time padding changes. Costs nothing at runtime.
**Caveat.** The container shape must be a rounded-rectangular shape
(`RoundedRectangle`, `Capsule`, `Circle`).
**Source.** Natalia Panferova, "Corner concentricity in SwiftUI on
iOS 26", nilcoalescing.com, 21 Aug 2025. Read 16 Aug 2026. Apple's own
skills shipped with Xcode 27 do not cover this.
@@ -0,0 +1,36 @@
# Programmatic scrolling
## `ScrollPosition` instead of `ScrollViewReader`
**What it is.** A `ScrollPosition` value held in `@State` and attached with
`.scrollPosition($position)` replaces wrapping content in a
`ScrollViewReader` to get at a proxy. Scrolling is then a method call on
the state — `position.scrollTo(id:)` — and, unlike the proxy, the value
can also be read, so the position is available both ways.
```swift
@State private var position = ScrollPosition()
ScrollView(.horizontal) {
HStack { ForEach(items) { ItemView(item: $0).id($0.id) } }
}
.scrollPosition($position)
```
Related, same family: `.defaultScrollAnchor(.bottom)` for where a view
starts out, and `onScrollGeometryChange(for:of:action:)` (iOS 18) for
following the offset while the user drags.
**What it replaces.** A `ScrollViewReader` wrapped around content purely
to reach `proxy.scrollTo` from a `.task`. In our card list that is the
filter chip strip, which scrolls the active chip into view.
**Step forward?** Modest but real. One layer of nesting disappears and the
scroll position stops being write-only. Not urgent — the existing code
works — so worth doing when that view is touched for another reason.
**Available since.** iOS 17, so nothing blocks it at our deployment
target. `onScrollGeometryChange` needs iOS 18.
**Source.** Natalia Panferova, "Modern SwiftUI APIs for programmatic
scrolling", nilcoalescing.com, 19 May 2026. Read 16 Aug 2026.
@@ -0,0 +1,31 @@
# Known, not yet usable
Things worth having, blocked on a deployment target. Kept so nobody
rediscovers them from scratch, and so the workarounds they replace can be
deleted the day the target moves.
## Adaptive toolbars (iOS 27)
**What it is.** Explicit control over how a toolbar collapses when it runs
out of room: `visibilityPriority` on a `ToolbarItem` (`.low`, `.automatic`,
`.high`, or custom levels declared relative to those), an explicit
`ToolbarOverflowMenu` for what should go into the overflow, and
`ToolbarItem(placement: .topBarPinnedTrailing)` for what must never move.
Related modifiers control minimisation on scroll.
**What it replaces.** A workaround we already carry: `.secondaryAction`
put our view-options menu into the system's own overflow, where it needed
two taps to open, so it was rebuilt as an ordinary primary-action button
with a hand-placed `ToolbarSpacer`. `visibilityPriority` plus
`ToolbarOverflowMenu` is the supported way to say what we meant.
**Step forward?** Yes, and it removes a comment explaining a hack.
**Blocked on.** Deployment target iOS 26. Either raise it or gate with
`#available`, which for a toolbar layout is more trouble than waiting.
**Source.** Natalia Panferova, "Adaptive SwiftUI toolbars in iOS 27",
nilcoalescing.com, 9 Aug 2026. Read 16 Aug 2026. Apple's
`swiftui-whats-new-27` skill covers the same APIs in more depth — prefer
it once the target moves; this entry exists for the "what of ours does it
replace" note.