- 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
```swift
// Minimal form — applies .regular glass with capsule shape
.glassEffect()
// Full form
.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)
```swift
.glassEffect(.regular.tint(.blue)) // semantic color tint
.glassEffect(.regular.interactive()) // enable touch responsiveness (iOS only)
.glassEffect(.clear.tint(.red).interactive()) // chainable
```
#### 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
```swift
// GlassEffectContainer wraps multiple glass views and composites them
// together so they sample background content once and morph as a unit.
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:
```swift
@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
```objc
// Subclass of UIVisualEffect
@interface UIGlassEffect : UIVisualEffect
// Factory method — preferred over alloc/init
+ (instancetype)effectWithStyle:(UIGlassEffectStyle)style;
@property (nonatomic) BOOL interactive; // enables touch response
@property (nonatomic, strong) UIColor *tintColor;
@end
// Enum values
typedef NS_ENUM(NSInteger, UIGlassEffectStyle) {
UIGlassEffectStyleRegular = 0,
UIGlassEffectStyleClear = 1,
};
```
#### UIGlassEffectView
```objc
// Works like UIVisualEffectView: add subviews to its contentView
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.
```objc
UIGlassEffectContainerView *container = [[UIGlassEffectContainerView alloc] init];
[container addSubview:glassViewA];
[container addSubview:glassViewB];
```
### AppKit APIs (macOS 26 / Tahoe)
#### NSGlassEffectView
```objc
// Embed content on a glass background — add your views to contentView
@interface NSGlassEffectView : NSView
@property (nonatomic, strong) NSView *contentView;
@property (nonatomic) CGFloat cornerRadius;
@property (nonatomic, strong) NSColor *tintColor;
@end
// Usage pattern
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.
```objc
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:
```crystal
# 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 |
在 GitHub 查看