ios_liquid_glass 0.9.9
ios_liquid_glass: ^0.9.9 copied to clipboard
Native iOS 26 Liquid Glass (UIGlassEffect and UITabBarController) for Flutter, plus an Impeller liquid-lens tier for iridescent droplet navigation.
ios_liquid_glass #
Apple's native iOS 26 Liquid Glass for Flutter — real UIGlassEffect
surfaces and the real UITabBarController tab bar — plus an Impeller
liquid lens tier for the iridescent droplet bottom nav that refracts
Flutter content (rainbow rim, jelly morph).
![]() |
![]() |
|---|
Left — liquid tier: the Impeller droplet caught mid-morph on the
example's Droplet lens page. This is real refraction of Flutter pixels:
"Night Swim" bends through the lens and the rim splits the backdrop into a
rainbow. Right — native tier: Apple's real UITabBarController and
UIGlassEffect buttons/cards on iOS 26.

The jelly morph between tabs (LiquidGlassBottomNav.liquid), recorded
on the iOS 26.2 Simulator. The droplet squash-stretches with spring physics
and keeps refracting the page content the whole way.

Lens close-up: chromatic aberration splits the backdrop like a prism.
Tune the rim strength with chromaticAberration (default 0.02; the shots
here use 0.06).
![]() |
![]() |
|---|
The native tier in motion: pushing any route hides the system tab bar
with zero manual wiring — see
LiquidGlassNavigatorObserver — and
declarative badges render on the real UITabBar. The Simulator exaggerates
native glass artifacts more than a device does — see
Known limitations.
| Tier | When | Rendering |
|---|---|---|
| liquid | LiquidGlassBottomNav.liquid / preferLiquid: true |
Impeller live-backdrop droplet (needs Impeller) |
| native | iOS 26+ default | Native UIGlassEffect platform view / system UITabBar |
| plain | everything else | Solid surface, identical layout |
Important: Native
UIGlassEffectis decorative — it samples layers beneath the Flutter view and does not refract Flutter pixels. For the floating rainbow droplet over your icons/page, use the liquid tier and stack the bar over content.
Install #
dependencies:
ios_liquid_glass:
path: /path/to/flutter_liquid_glass # or ^0.9.0 from pub
Host app requirements #
- iOS
Info.plist— enable platform views (native tier) and Impeller (liquid tier):<key>io.flutter.embedded_views_preview</key> <true/> <key>FLTEnableImpeller</key> <true/> - iOS 26+ SDK on the build machine for native glass (deployment target can stay lower).
- Full restart after enabling Impeller (hot reload is not enough).
Usage #
Drop-in tab host (recommended) #
Register the package observer once — this alone makes the native bar hide on any pushed route (PIN, Order New Card, a details page, ...) and reappear on pop, with no per-route bookkeeping:
MaterialApp(
navigatorObservers: [LiquidGlassNavigatorObserver.instance],
// or with a router:
// routerDelegate: appRouter.delegate(
// navigatorObservers: () => [LiquidGlassNavigatorObserver.instance],
// ),
home: const RootTabs(),
)
Then build the tab host:
import 'package:ios_liquid_glass/ios_liquid_glass.dart';
LiquidGlassTabScaffold(
currentIndex: index,
onIndexChanged: (i) => setState(() => index = i),
destinations: [
LiquidGlassTabDestination(
title: 'Home',
systemImage: 'house',
selectedSystemImage: 'house.fill',
icon: const Icon(Icons.home_outlined),
selectedIcon: const Icon(Icons.home),
page: const HomePage(),
),
LiquidGlassTabDestination(
title: 'Search',
systemImage: 'magnifyingglass',
icon: const Icon(Icons.search),
page: const SearchPage(),
),
],
)
For hiding driven by app state instead of (or in addition to) route
pushes — a PIN screen or blur overlay modeled as a flag rather than a
route — add barVisible and/or shouldHideOverlay:
LiquidGlassTabScaffold(
currentIndex: index,
onIndexChanged: (i) => setState(() => index = i),
barVisible: !isPinOpen, // app-driven flag
shouldHideOverlay: () => isPinOpen || isBlurOpen, // same-frame check
overlayListenable: router, // extra listenable to resync on
destinations: [ /* ... */ ],
)
Use .shell when you already own the page stack:
LiquidGlassTabScaffold.shell(
currentIndex: index,
onIndexChanged: onIndexChanged,
themeBuilder: (context) => LiquidGlassTheme.adaptive(context),
overlayListenable: router,
nativeTabs: [...],
fallbackItems: [...],
child: yourBody,
)
Scroll views should use MediaQuery.paddingOf(context).bottom (applied
automatically when applyContentInset: true).
Liquid droplet bottom nav (matches the morphing lens look) #
import 'package:ios_liquid_glass/ios_liquid_glass.dart';
Scaffold(
body: Stack(
fit: StackFit.expand,
children: [
Padding(
padding: EdgeInsets.only(
bottom: LiquidGlassBottomNav.contentBottomClearance(context),
),
child: yourPage,
),
LiquidGlassBottomNav.liquid(
currentIndex: index,
onIndexChanged: (i) => setState(() => index = i),
items: [
LiquidGlassNavItem.custom(
iconBuilder: (context, g) => SvgPicture.asset(
g.selected ? 'assets/home_fill.svg' : 'assets/home.svg',
width: g.size,
height: g.size,
colorFilter: ColorFilter.mode(g.color, BlendMode.srcIn),
),
),
// ...
],
),
],
),
);
Tune the rainbow rim with chromaticAberration (default 0.02; the README
shots use 0.06). See the Droplet lens page in example/lib/main.dart
(DropletNavDemoPage) for the exact setup behind the screenshots.
Native glass card / buttons (iOS 26+) #
LiquidGlassContainer(
borderRadius: 24,
style: const LiquidGlassStyle(
nativeVariant: NativeGlassVariant.clear,
),
child: const Text('Hello, glass'),
)
Capability detection #
if (LiquidGlassPlatform.supportsLiquidLens) { ... }
if (LiquidGlassPlatform.supportsNativeGlass) { ... } // iOS 26+
The real system tab bar (advanced) #
LiquidGlassNativeTabShell overlays Apple's actual UITabBarController
(iOS 26+) — see previous docs / example for install, badges, route sync,
and modals.
Known limitations #
- Native
UIGlassEffectdoes not refract Flutter-drawn pixels. - Liquid tier needs Impeller; on Skia/Web it falls back to a frosted bar.
- Custom native-tab icons must be pre-rasterized PNG bytes.
- The iOS Simulator exaggerates native Liquid Glass artifacts; judge native visuals on a device. Liquid Impeller refraction is fine on sim.
Example #
example/lib/main.dart — a four-tab LiquidGlassTabScaffold (Home,
Search, Favorites, Profile) wired the way a host app is meant to:
LiquidGlassNavigatorObserver registered once on the MaterialApp, a
Navigator.push from Home that hides the bar with no extra code, a
barVisible toggle for app-driven hiding (PIN screens, blur overlays),
declarative tab badges, and the button/icon-button gallery from the
screenshots above. Native tab shell on iOS 26+, Flutter fallback bars
everywhere else.
The Liquid droplet nav button on Home pushes DropletNavDemoPage —
the page behind the hero shots: LiquidGlassBottomNav.liquid stacked over
a colorful library grid so the droplet has real content to refract (the
system bar hides itself for the pushed route, so the two bars never
fight).
cd example
flutter run



