mirror of
https://github.com/Dimillian/Skills.git
synced 2026-04-27 14:57:40 +00:00
Introduces the 'swiftui-ui-patterns' skill to docs/skills.json, providing best practices and example-driven guidance for building SwiftUI views and components. Adds SKILL.md and a comprehensive set of reference files covering TabView, NavigationStack, sheets, forms, controls, grids, overlays, haptics, focus handling, media, matched transitions, split views, and more.
1.6 KiB
1.6 KiB
Matched transitions
Intent
Use matched transitions to create smooth continuity between a source view (thumbnail, avatar) and a destination view (sheet, detail, viewer).
Core patterns
- Use a shared
Namespaceand a stable ID for the source. - Use
matchedTransitionSource+navigationTransition(.zoom(...))on iOS 26+. - Use
matchedGeometryEffectfor in-place transitions within a view hierarchy. - Keep IDs stable across view updates (avoid random UUIDs).
Example: media preview to full-screen viewer (iOS 26+)
struct MediaPreview: View {
@Namespace private var namespace
@State private var selected: MediaAttachment?
var body: some View {
ThumbnailView()
.matchedTransitionSource(id: selected?.id ?? "", in: namespace)
.sheet(item: $selected) { item in
MediaViewer(item: item)
.navigationTransition(.zoom(sourceID: item.id, in: namespace))
}
}
}
Example: matched geometry within a view
struct ToggleBadge: View {
@Namespace private var space
@State private var isOn = false
var body: some View {
Button {
withAnimation(.spring) { isOn.toggle() }
} label: {
Image(systemName: isOn ? "eye" : "eye.slash")
.matchedGeometryEffect(id: "icon", in: space)
}
}
}
Design choices to keep
- Prefer
matchedTransitionSourcefor cross-screen transitions. - Keep source and destination sizes reasonable to avoid jarring scale changes.
- Use
withAnimationfor state-driven transitions.
Pitfalls
- Don’t use unstable IDs; it breaks the transition.
- Avoid mismatched shapes (e.g., square to circle) unless the design expects it.