swiftui-26-api
SwiftUI 26 API Reference
Non-glass SwiftUI APIs introduced at WWDC 2025 targeting iOS 26, macOS 26, visionOS 26. Synthesized from official Apple documentation (via sosumi.ai extractions).
For Liquid Glass APIs (
glassEffect,GlassEffectContainer,backgroundExtensionEffect, morph animations), loadapple-liquid-glass-designskill instead.
Quick Reference
Animation
1. @Animatable Macro
iOS 13+ · macOS 10.15+ (Swift 5.9+ compiler required)
Auto-synthesizes animatableData from the struct's numeric properties. Non-animatable properties must use @AnimatableIgnored.
@Animatable
struct CoolShape: Shape {
var width: CGFloat
var angle: Angle
@AnimatableIgnored var isOpaque: Bool
// animatableData synthesized from width + angle
}
Text Editing
2. AttributedString TextEditor with Selection
iOS 26+ · macOS 26+
Use TextEditor with an AttributedString binding and AttributedTextSelection to track the insertion point or selected range.
struct SuggestionTextEditor: View {
@State var text: AttributedString = ""
@State var selection = AttributedTextSelection()
var body: some View {
VStack {
TextEditor(text: $text, selection: $selection)
SuggestionsView(substrings: getSubstrings(
text: text, indices: selection.indices(in: text)))
}
}
}
3. Formatting Definition
iOS 26+ · macOS 26+
Define an AttributedTextFormattingDefinition to restrict which formatting attributes are valid in a TextEditor.
struct MyTextFormattingDefinition: AttributedTextFormattingDefinition {
var body: some AttributedTextFormattingDefinition<
AttributeScopes.SwiftUIAttributes
> {
ValueConstraint(
for: \.underlineStyle,
values: [nil, .single],
default: .single)
MyAttributedTextValueConstraint()
ContactsArePurple()
}
}
Web Content
4. WebView with WebPage Controller
iOS 26+ · macOS 26+ · visionOS 26+ (requires import WebKit)
Displays web content in a native SwiftUI view. Connect a WebPage controller for navigation, JavaScript, and title binding.
import WebKit
struct ContentView: View {
@State private var page = WebPage()
var body: some View {
NavigationStack {
WebView(page)
.navigationTitle(page.title)
}
}
}
UIKit Bridge
5. UIHostingSceneDelegate
iOS 26+ · iPadOS 26+ · tvOS 26+ · visionOS 26+
Use UIHostingSceneDelegate to activate SwiftUI scenes from a UIKit app.
class HostingSceneDelegate: UIHostingSceneDelegate {
static var rootScene: some Scene {
WindowGroup(id: "swiftui-window") {
ContentView()
}
}
}
// Activate from UIKit:
if let request = UISceneSessionActivationRequest(
hostingDelegateClass: HostingSceneDelegate.self,
id: "swiftui-window"
) {
UIApplication.shared.activateSceneSession(for: request)
}
Scroll & Tab Behavior
6. Scroll Edge Effect
iOS 26+ · macOS 26+
ScrollView {
LazyVStack {
ForEach(data) { item in
RowView(item)
}
}
}
.scrollEdgeEffectStyle(.hard, for: .all)
7. Tab Bar Minimization
iOS 26+ · macOS 26+
TabView {
Tab("Numbers", systemImage: "number") {
ScrollView {
ForEach(0 ..< 50) { index in
Text("\(index)").padding()
}
}
}
}
.tabBarMinimizeBehavior(.onScrollDown)
Toolbar & Layout
8. Toolbar Spacer
iOS 26+ · iPadOS 26+ · macOS 26+
ContentView()
.toolbar(id: "main-toolbar") {
ToolbarItem(id: "tag") { TagButton() }
ToolbarItem(id: "share") { ShareButton() }
ToolbarSpacer(.fixed)
ToolbarItem(id: "more") { MoreButton() }
}
macOS Only
9. Window Resize Anchor — macOS 26
struct HeightResizingExample: View {
@State private var height: CGFloat = 300
var body: some View {
Color.red
.overlay { Text("Tap to toggle").foregroundStyle(.white) }
.onTapGesture {
withAnimation(.easeInOut) {
height = height == 300 ? 700 : 300
}
}
.frame(width: 250, height: height)
.windowResizeAnchor(.top)
}
}
10. Drag Container — macOS 26
VStack {
ForEach(fruits) { fruit in
FruitView(fruit)
.draggable(containerItemID: fruit.name)
}
}
.dragContainer(itemID: \Fruit.name) { ids in
fruits(with: ids)
}
Reading Paths
Clustered reference file sequences for common goals.
A — Adopting Liquid Glass:
Load apple-liquid-glass-design skill — it contains complete glass adoption paths.
B — Building a Rich Text Editor:
text-editing.md → find-context.md
C — Embedding Web Content:
webkit.md → uikit-scene-bridge.md (if UIKit host)
D — Migrating an Existing App:
Migration sections are embedded in each reference file: webkit.md (WKWebView → WebView), uikit-scene-bridge.md (UIHostingController → UIHostingSceneDelegate), animatable-macro.md (manual animatableData → @Animatable). For glass migration (.material → .glassEffect), see apple-liquid-glass-design.
E — macOS-Specific Features:
macos-drag-and-windows.md → toolbar-and-slider.md
F — Custom Shape Animation:
animatable-macro.md → apple-liquid-glass-design (if animating glass shapes)
Common Gotchas
WebPageis@MainActor— all interactions must happen on the main actor- One
WebPageperWebView— only oneWebPagecan bind to a singleWebViewat a time - Drag container APIs are macOS 26 only —
dragContaineranddraggable(containerItemID:)are not available on iOS @Animatableavailability is broad — the macro works back to iOS 13, but requires Swift 5.9+ compilerFindContextuses environment — access via@Environment(\.findContext), returns optionalTextEditorselection requiresAttributedString—AttributedTextSelectionbinding doesn't work with plainString
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
WebView type not found |
Missing framework import | Add import WebKit — WebView/WebPage are in WebKit, not SwiftUI |
@Animatable compilation error |
Compiler too old | Requires Swift 5.9+ (Xcode 15+), even though protocol availability is iOS 13+ |
scrollEdgeEffectStyle has no visible effect |
Applied to wrong container | Only works on ScrollView, not List |
UIHostingSceneDelegate callbacks not firing |
Missing scene declaration | Ensure static var rootScene is implemented and UISceneConfiguration.delegateClass is set |
FindContext is nil at runtime |
Not accessing via environment | Use @Environment(\.findContext) var findContext — returns optional |
WebPage.title is always nil |
Not stored as @State | Declare as @State private var page = WebPage() |
windowResizeAnchor ignored during shrink |
Missing resizability setting | Set .windowResizability(.contentSize) on the Scene |
AttributedTextSelection.indices returns empty |
Selection bound to String | TextEditor must use $attributedString binding, not $string |
dragContainer compile error on iOS |
macOS 26 only | Guard with #if os(macOS) |
Reference Files
| File | Read when... |
|---|---|
references/animatable-macro.md |
using @Animatable macro to synthesize animatableData |
references/text-editing.md |
building TextEditor with AttributedString, selection, or formatting definitions |
references/find-context.md |
implementing find/replace via FindContext |
references/webkit.md |
embedding web content with WebView or WebPage |
references/uikit-scene-bridge.md |
bridging UIKit scene lifecycle to SwiftUI via UIHostingSceneDelegate |
references/macos-drag-and-windows.md |
adding dragContainer/draggable or windowResizeAnchor (macOS 26 only) |
references/scroll-and-tabs.md |
configuring scrollEdgeEffectStyle or tabBarMinimizeBehavior |
references/toolbar-and-slider.md |
adding ToolbarSpacer or Slider tick marks |
Cross-References
apple-liquid-glass-design— All Liquid Glass APIs (glassEffect, GlassEffectContainer, backgroundExtensionEffect, morph animations)swiftui-input-api— Pre-iOS 26 TextEditor, text fields, pickersswift-app-lifecycle— Scene phase management, app entry pointsswiftui-effects-api— Pre-iOS 26 blur, shadow, opacity effects