| name | ios26-native-components |
| description | Complete catalog of iOS 26 and macOS 26 native UI components including SwiftUI views,
UIKit classes, and AppKit classes. Covers Liquid Glass design language, new WWDC 2025
APIs, and mapping guidance for Crystal cross-platform UI integration.
|
| user-invocable | true |
| allowed-tools | Read, Write, Edit, Glob, Grep, Bash, WebSearch, WebFetch |
| version | 1.0.0 |
iOS 26 / macOS 26 Native Components Reference
This document is the authoritative reference for native Apple platform UI components
available in iOS 26, iPadOS 26, and macOS Tahoe 26. It covers the Liquid Glass design
language introduced at WWDC 2025, all major SwiftUI views, UIKit view classes, and
AppKit view classes. It provides implementation priority guidance for the
asset_pipeline Crystal library's PlatformVisitor system.
The asset_pipeline maps Crystal UI::View types to native platform elements at compile
time. For macOS, the AppKit::Renderer (in src/ui/renderers/appkit_renderer.cr)
allocates AppKit classes via the ObjC runtime bridge. For iOS, the same pattern applies
using UIKit classes. For web, the WebRenderer emits HTML/CSS.
1. Overview
iOS 26 and macOS Tahoe 26, released at WWDC 2025, introduce the most significant visual
redesign since iOS 7. The new "Liquid Glass" material system replaces flat and frosted
designs with a physically-based translucency that bends and refracts light in real time.
Every major UI surface is updated: tab bars, toolbars, sheets, navigation bars, and
control backgrounds now render with Liquid Glass. Developers can apply the material to
their own views using new SwiftUI modifiers (.glassEffect()), new UIKit classes
(UIGlassEffect, UIGlassEffectView, UIGlassEffectContainerView), and new AppKit
classes (NSGlassEffectView, NSGlassEffectContainerView).
Beyond the visual system, iOS 26 adds two long-requested features: a native SwiftUI
WebView type (eliminating the need for UIKit wrapping of WKWebView) and rich-text
editing in TextEditor via AttributedString. Other additions include 3D charting with
Chart3D, enhanced TabView with collapse-on-scroll behavior, ToolbarSpacer, list
section index labels, the @Animatable macro, new SF Symbols draw-on effects, and the
.backgroundExtensionEffect() modifier.
2. Liquid Glass Design Language (iOS 26 / macOS 26)
What Liquid Glass Is
Liquid Glass is Apple's new material introduced across all Apple platforms in 2025. It
is a translucent, physically-based surface that:
- Refracts and lenses light - uses real-time lensing (not blur-scatter like Gaussian
blur) to bend the content behind the glass surface
- Responds to device motion - specular highlights shift as the device tilts
- Adapts to background content - the frosting and tinting adjust to remain legible
over any background color, image, or video
- Morphs between states - adjacent glass elements can merge and separate with fluid
animations when assigned matching IDs within a shared namespace
- Supports interactive behaviors - when
.interactive() is applied, touch events
cause the glass to scale, bounce, shimmer, and light up at the contact point
- Adapts to accessibility settings - automatically increases frosting when
reduceTransparency is enabled; reduces motion when reduceMotion is enabled
Liquid Glass replaces UIVisualEffectView / NSVisualEffectView as the primary
background material for controls and navigation chrome. The old blur/vibrancy APIs
remain available but are not used by system-provided controls in iOS 26.
SwiftUI APIs
Primary Modifier
.glassEffect()
.glassEffect(_ glass: GlassEffect, in shape: some Shape, isEnabled: Bool = true)
Glass Variants
| Variant | Transparency | Typical Use |
|---|
.regular | Medium | Toolbars, buttons, navigation bars |
.clear | High (minimal frosting) | Floating controls over photos/video |
.identity | None (disabled) | Conditional toggling without layout change |
Glass Modifiers (chained on GlassEffect)
.glassEffect(.regular.tint(.blue))
.glassEffect(.regular.interactive())
.glassEffect(.clear.tint(.red).interactive())
Supported Shapes
.capsule (default when no shape specified)
.circle
.ellipse
RoundedRectangle(cornerRadius: 12)
.rect(cornerRadius: .containerConcentric) — auto-aligns corner radius with parent
- Any custom type conforming to the
Shape protocol
Morphing and Grouping
GlassEffectContainer(spacing: 8) {
Button("A") { }
.glassEffect()
.glassEffectID("buttonA", in: namespace)
Button("B") { }
.glassEffect()
.glassEffectID("buttonB", in: namespace)
}
GlassEffectContainer(spacing:) — groups glass elements; ensures uniform
background sampling and enables morphing transitions
.glassEffectID(_ id:, in: Namespace.ID) — assigns identity so elements can
morph into each other during state changes; requires a @Namespace variable
Accessibility Environment
The glass system reads these environment values automatically:
@Environment(\.accessibilityReduceTransparency) var reduceTransparency
@Environment(\.accessibilityReduceMotion) var reduceMotion
No code required — Apple's implementation increases frosting when transparency is
reduced and disables physics-based animations when reduce motion is active.
UIKit APIs (iOS 26 / iPadOS 26)
Class Hierarchy
UIVisualEffect
└── UIGlassEffect (NEW in iOS 26)
UIView
└── UIVisualEffectView
└── UIGlassEffectView (NEW in iOS 26)
└── UIGlassEffectContainerView (NEW in iOS 26)
UIGlassEffect
@interface UIGlassEffect : UIVisualEffect
+ (instancetype)effectWithStyle:(UIGlassEffectStyle)style;
@property (nonatomic) BOOL interactive;
@property (nonatomic, strong) UIColor *tintColor;
@end
typedef NS_ENUM(NSInteger, UIGlassEffectStyle) {
UIGlassEffectStyleRegular = 0,
UIGlassEffectStyleClear = 1,
};
UIGlassEffectView
UIGlassEffect *glass = [UIGlassEffect effectWithStyle:UIGlassEffectStyleRegular];
UIGlassEffectView *glassView = [[UIGlassEffectView alloc] initWithEffect:glass];
glassView.layer.cornerRadius = 20;
glassView.clipsToBounds = YES;
[glassView.contentView addSubview:myLabel];
UIGlassEffectContainerView
Groups multiple UIGlassEffectView instances so they sample the background together
and morph as a unit. Add UIGlassEffectView instances as subviews of the container.
UIGlassEffectContainerView *container = [[UIGlassEffectContainerView alloc] init];
[container addSubview:glassViewA];
[container addSubview:glassViewB];
AppKit APIs (macOS 26 / Tahoe)
NSGlassEffectView
@interface NSGlassEffectView : NSView
@property (nonatomic, strong) NSView *contentView;
@property (nonatomic) CGFloat cornerRadius;
@property (nonatomic, strong) NSColor *tintColor;
@end
NSGlassEffectView *glassView = [[NSGlassEffectView alloc] initWithFrame:frame];
glassView.cornerRadius = 12;
glassView.tintColor = [NSColor systemBlueColor];
[glassView.contentView addSubview:myControl];
NSGlassEffectContainerView
Groups multiple NSGlassEffectView instances for unified background sampling and
morphing. Equivalent to UIGlassEffectContainerView on iOS.
NSGlassEffectContainerView *container = [[NSGlassEffectContainerView alloc] initWithFrame:frame];
[container addSubview:glassViewA];
[container addSubview:glassViewB];
Crystal Integration Notes
The existing glass-effects skill covers Liquid Glass integration patterns for
asset_pipeline. The UIKit path would add a UI::GlassEffect view that wraps
UIGlassEffectView on iOS and NSGlassEffectView on macOS. Web rendering would
use CSS backdrop-filter: blur() with a translucent background color as the
closest equivalent.
Crystal ObjC bridge pattern for NSGlassEffectView:
# In AppKit::Renderer
def visit(view : UI::GlassView)
ptr = alloc_init("NSGlassEffectView")
LibObjCBridge.objc_send_1d(ptr, sel("setCornerRadius:"), view.corner_radius)
if tint = view.tint
tint_ptr = LibObjCBridge.nscolor_rgba(tint.r, tint.g, tint.b, tint.a)
LibObjCBridge.objc_send_id(ptr, sel("setTintColor:"), tint_ptr)
end
# contentView is a property — get it and add children to it
content_view = LibObjCBridge.objc_send(ptr, sel("contentView"))
# ... add arranged subviews to content_view ...
apply_common_properties(ptr, view)
emit(ptr, "NSGlassEffectView")
end
3. SwiftUI Views by Category
For each view: SwiftUI name, underlying UIKit/AppKit class, Crystal UI::View equivalent
or proposed name, and implementation priority.
Legend for Crystal column:
UI::Label — already implemented
UI::Toggle (proposed) — not yet implemented, new view needed
- — — no Crystal equivalent planned / low priority
Legend for Priority:
- P0 — already implemented
- P1 — high priority, common daily-use patterns
- P2 — medium priority, rich interactions
- P3 — lower priority, specialized use cases
- iOS26 — new in iOS 26 / WWDC 2025
3.1 Layout
| SwiftUI View | UIKit Class | AppKit Class | Crystal Equivalent | Priority |
|---|
VStack | — (Auto Layout) | NSStackView (orientation=1) | UI::VStack | P0 |
HStack | — (Auto Layout) | NSStackView (orientation=0) | UI::HStack | P0 |
ZStack | — (Auto Layout) | NSView (manual subviews) | UI::ZStack | P0 |
Spacer | — | NSView (flexible) | UI::Spacer | P0 |
LazyVStack | — | — | UI::LazyVStack (proposed) | P2 |
LazyHStack | — | — | UI::LazyHStack (proposed) | P2 |
Grid | — (compositional) | — | UI::Grid (proposed) | P2 |
GridRow | — | — | UI::GridRow (proposed) | P2 |
LazyVGrid | UICollectionView | NSCollectionView | UI::LazyVGrid (proposed) | P2 |
LazyHGrid | UICollectionView | NSCollectionView | UI::LazyHGrid (proposed) | P2 |
ViewThatFits | — | — | — | P3 |
AnyLayout | — | — | — | P3 |
GeometryReader | — | — | — | P3 |
Group | — (no-op container) | — | — | P2 |
Section | — | — | — | P2 |
Notes:
LazyVStack / LazyHStack defer child view creation until needed; UIKit equivalent
is UICollectionView with a diffable data source.
Grid is a two-dimensional layout container (iOS 16+, not lazy). On UIKit it
requires UICollectionViewCompositionalLayout.
ViewThatFits tries views in order and uses the first one that fits in its proposed
size. No direct UIKit equivalent; requires measurement logic.
3.2 Scroll and Lists
| SwiftUI View | UIKit Class | AppKit Class | Crystal Equivalent | Priority |
|---|
ScrollView | UIScrollView | NSScrollView | UI::ScrollView | P0 |
List | UITableView (older) / UICollectionView (newer) | NSTableView | UI::List (proposed) | P1 |
Form | UITableView (grouped) | — | UI::Form (proposed) | P2 |
Table | UICollectionView | NSTableView | UI::Table (proposed) | P2 |
OutlineGroup | — | NSOutlineView | — | P3 |
DisclosureGroup | — | NSDisclosureButton + content | UI::DisclosureGroup (proposed) | P2 |
ForEach | — (data-driven loop) | — | — (handled in Crystal loop) | P1 |
ScrollViewReader | — | — | — | P2 |
LazyVStack (in ScrollView) | UICollectionView | NSCollectionView | — | P2 |
Notes:
List in SwiftUI renders as a UICollectionView since iOS 16 (previously
UITableView). The AppKit renderer maps to NSTableView.
Form is a styled List for settings-style data entry; UIKit uses grouped
UITableView style.
Table is a multi-column tabular display (iOS 16+ / macOS 12+); AppKit uses
NSTableView with multiple NSTableColumn instances.
3.3 Text
| SwiftUI View | UIKit Class | AppKit Class | Crystal Equivalent | Priority |
|---|
Text | UILabel | NSTextField (non-editable) | UI::Label | P0 |
Label (icon+text) | UILabel + UIImageView | NSTextField + NSImageView | — (compose manually) | P2 |
TextEditor | UITextView | NSTextView | UI::TextEditor (proposed) | P1 |
TextField | UITextField | NSTextField (editable) | UI::TextField | P0 |
SecureField | UITextField (secureTextEntry=YES) | NSSecureTextField | UI::TextField (secure_entry: true) | P0 |
TextEditor (AttributedString) | UITextView | NSTextView | UI::RichTextEditor (proposed) | P2 |
Notes:
- SwiftUI
Text maps to a read-only text display. In the AppKit renderer this is
NSTextField with setEditable:NO, setBezeled:NO, setDrawsBackground:NO.
- In iOS 26,
TextEditor now accepts AttributedString for rich text editing
(bold, italic, color, links). This is NEW in iOS 26.
Label (the SwiftUI view with an icon slot) is distinct from Text. It displays
a system SF Symbol alongside text. No single UIKit class; compose from
UILabel + UIImageView in a horizontal arrangement.
3.4 Images and Media
| SwiftUI View | UIKit Class | AppKit Class | Crystal Equivalent | Priority |
|---|
Image | UIImageView | NSImageView | UI::Image | P0 |