cupertino_native_better 1.4.5
cupertino_native_better: ^1.4.5 copied to clipboard
Native iOS Liquid Glass widgets for Flutter with pixel-perfect fidelity. Includes Button, Icon, TabBar, Slider, Switch, and more with reliable version detection.
1.4.5 #
Bug Fixes #
-
Fixed #35 / #41 (recreate animation on launch + navigation) —
CNTabBarno longer plays a visible "morph through every tab" animation on app launch or after navigating away and back.- Launch glitch (#35): Swift
refreshcyclesbar.selectedItemthrough every tab to force UITabBar's label layout (workaround for an old "5 items, sporadic missing labels" bug — Issue #6). On iOS 26 with Liquid Glass, that cycling was visible as the selection pill morphing through every tab. The cycle is now wrapped inUIView.setAnimationsEnabled(false) … true— labels still render correctly, but the pill no longer animates between items. Tab bar appears instantly with the configuredcurrentIndex. - Recreate-on-return (#41 part 1):
autoHideOnPageTransitionpreviously swapped the platform view to aSizedBoxduring route slides, destroying the nativeUITabBar. On return, a fresh view was created and_onCreatedre-ransetSelectedIndex+refresh→ visible animate-to-index. Fix: whenautoHideOnPageTransitionis on,CNTabBar.buildnow always returns anIndexedStack(children:[SizedBox, UiKitView]); only the painted index toggles between 0 and 1 across the transition. TheUiKitView's element stays mounted in both states, so the nativeUITabBaris preserved across navigation. Bar just appears with the correct index, no animation.
- Launch glitch (#35): Swift
-
Fixed #41 (PlatformViewGuard 500 ms fallback flash on first build) — non-iOS26 fallback widgets briefly visible during cold start.
- Cause:
PlatformViewGuard.ensureScheduledalways delayed platform-view creation by 500 ms to give Flutter'sFlutterPlatformViewsControllertime to purge stale registrations from a previous Dart isolate after a hot restart. That race only exists in debug; release builds (cold-start, no isolate recycling) were paying the same flash-of-fallback cost for nothing. - Fix:
PlatformViewGuardis now ready immediately inkReleaseMode. Native iOS 26 widgets render from the first frame in production; debug-mode hot-restart safety is preserved unchanged.
- Cause:
-
Fixed #36 follow-up —
LiquidGlassContainer's rectangular layer drop shadow leaking past its rounded glass corners while a modal/sheet was presented above (was already targeted in v1.4.4 but only clipped the rectangular layer bounds; rounded clip wasn't applied across all shape configurations correctly). The corner-radius clip inapplyTransitionContainmentnow consistently matchesrect(configured cornerRadius),capsule(min(width, height)/2), andcircle(min(width, height)/2) — no more square shadow nubs.
New #
-
Fixed #40 (CNButton label customization) —
CNButtonConfignow accepts:labelFontFamily— custom font family (must be registered inInfo.plistor as a Flutter font asset).labelFontSize— point size override.labelColor— explicit foreground color (overrides thetint-derived default for non-filled styles, and the system default for filled / borderedProminent / prominentGlass).labelFontWeight— FlutterFontWeightoverride.
Implementation: Swift side applies them via
UIButton.Configuration.titleTextAttributesTransformer, so the overrides take effect on the native label without losing the iOS 26 Liquid Glass / prominent / tinted button background. Both creation-time (creationParams) and runtime (setLabelStylechannel call from_syncPropsToNativeIfNeeded) updates are supported. FlutterFontWeight.value(0-8) is mapped toUIFont.Weight.Example:
CNButton( label: '1', tint: CupertinoColors.systemOrange, onPressed: () {}, config: const CNButtonConfig( style: CNButtonStyle.prominentGlass, width: 80, minHeight: 80, labelFontSize: 36, labelFontWeight: FontWeight.w600, labelColor: CupertinoColors.white, ), )
Behavioural details #
CNTabBar.autoHideOnPageTransitionkeeps its defaulttrue. With the IndexedStack-based hide it's now zero-cost: state is preserved across navigation while still preventing the original page-wide PlatformViewLayer occlusion artifact during route slides.- Multi-label
CNButton(e.g. dial-pad style: large number + small letters underneath) is intentionally not added toCNButton's API. The same effect composes cleanly viaLiquidGlassContainerwrapping aColumnof two FlutterTexts — fullTextStylefreedom on both labels with the native iOS 26 Liquid Glass background. See the closing comment on Issue #40 for a snippet.
Example app #
- Added:
Testing → #40: CNButton label style— interactive screen for verifying the new label-style params (font-size slider, color swatches, font-family segmented control, style picker).
Pana #
- 160/160
1.4.4 #
Bug Fixes #
- Fixed #36 —
LiquidGlassContainer's rectangular layer drop shadow leaking past its rounded glass corners while a modal/sheet was presented above. Visible as four square shadow nubs at the card's corners through the modal's scrim, even though the visible glass was rounded.- Root cause:
applyTransitionContainment(true)(added in v1.4.3 for the dynamic halo containment) only setclipsToBounds = trueon the container's CALayer, which clips to the rectangular layer bounds — leaving the four corners outside the rounded glass shape unclipped. The layer's drop shadow rendered into those corners and bled through the modal scrim. - Fix: in
LiquidGlassContainerView.swift,applyTransitionContainment(true)now also setscontainer.layer.cornerRadius(and the hosting view's) to match the configured glass shape:rectshape → uses the configuredcornerRadiuscapsule/circle→min(width, height) / 2
- The clip is now rounded, matching the visible glass exactly. Reverted to 0 when containment goes inactive so it doesn't affect the at-rest visual.
- Root cause:
Documentation #
- README: added a prominent "Required Setup: register
CNTabBarRouteObserver" section directly under Quick Start, documenting:- Why the observer is needed (hybrid composition, halo containment, z-order with sheets).
- Where to register it:
CupertinoApp/MaterialApp/GoRoutersnippets. - What it fixes across all 7 glass widgets, with explicit references to Issues #29, #31, #36.
- Manual
markAnyModalActive/markAnyModalInactiveAPI for non-route overlays (Scaffold.showBottomSheet). - Several users reported needing this observer to fix sheet bleed-through; with this section it should now be impossible to miss during initial setup.
Example app #
- Added:
Testing → #36: LiquidGlassContainer behind modal— focused reproduction page for Issue #36. Card-shapedLiquidGlassContainermatching the issue reporter's_AdaptiveGlassContainerwidget exactly (cornerRadius: 15,rect,EdgeInsets.all(13), no tint), four sheet variants including the reporter's exactshowModalBottomSheetinvocation (rounded top, scaffold-bg,Clip.antiAlias, bounce animation,useRootNavigator: true), and aCalendarDatePickerinside each sheet matching the modal content from the issue's screenshots. White scaffold + black/white pill buttons mirror the reporter's app styling.
Pana #
- 160/160
1.4.3 #
Bug Fixes #
-
Fixed #34 — CNButton glass capsule not stretching with its parent frame; icon overflowing a small pill when wrapped in
SizedBox/Expanded. Regression introduced in v1.4.0.- Root cause: the v1.4.0 "feat: fixes" commit added always-on
container.clipsToBounds = true+uiButton.clipsToBounds = true(plus layer shadow/background clearing) across every iOS 26 glass widget as part of the #29 halo containment.UIButton.Configuration.glass()renders its capsule via an internal background subview whose visual size includes a soft-edge glow extending slightly beyond the button's layer bounds — the always-on clipping was cropping that glow AND preventing the capsule from growing with a stretched frame. - Fix: reverted all the always-on clipping across
CNButton,CNPopupMenuButton,CNFloatingIsland,CNGlassButtonGroup,LiquidGlassContainer,CNSearchBar. Containers are unclipped at rest, so the glass capsule renders its full soft-edge glow and stretches properly withSizedBox/Expanded/Container(width: ...).
- Root cause: the v1.4.0 "feat: fixes" commit added always-on
-
Fixed #29 (fully) — the original halo-during-route-transition artifact is now resolved via a dynamic containment pattern instead of always-on clipping. This also catches the popup/sheet bleed cases that the v1.4.0 fix didn't cover (popup routes, persistent bottom sheets).
- New native method
setTransitioning(active:)onCNButton,CNPopupMenuButton,CNFloatingIsland,CNGlassButtonGroup,LiquidGlassContainer,CNSearchBar, and the regularCNTabBarvariant. When active, it applies the halo-containment clipping + shadow/background clearing; when inactive, it reverts. - Dart side listens to two signals and calls
setTransitioning(true)when either fires:ModalRoute.secondaryAnimation— catchesCupertinoPageRoute/MaterialPageRouteforward/reverse transitions.- A new
CNTabBarRouteObserver.anyModalDepthcounter that tracks anyPopupRoute/ Sheet / Popup / Dialog-named route (showCupertinoSheet,showCupertinoModalPopup,showModalBottomSheet,DialogRoute, etc.).
- For the split-search variant of
CNTabBar(whose native container is intentionally unclipped so the floating search orb can render above the bar), the auto-hide trigger is broadened toanyModalDepthso popups over a search-enabled tab bar no longer leak shadow through the sheet's top edge.
- New native method
New #
-
CNTabBarRouteObserver.anyModalDepth(read-onlyValueListenable<int>) — broader counter than the existingmodalDepth. Tracks every modal-like route (allPopupRoutes plus any route whose runtime type containsSheet/Popup/Dialog). Used internally by the glass widgets for halo-containment activation. -
CNTabBarRouteObserver.markAnyModalActive()/markAnyModalInactive()— public manual API for non-route overlays thatNavigatorObservercan't see, notablyScaffold.showBottomSheet(persistent bottom sheet anchored toScaffoldState, not the Navigator):final controller = Scaffold.of(context).showBottomSheet(...); CNTabBarRouteObserver.markAnyModalActive(); controller.closed.whenComplete(CNTabBarRouteObserver.markAnyModalInactive);
Example app #
- Added:
Testing → CNButton modal halo test— stretched CNButton variants + 4 sheet types (showCupertinoSheet,showCupertinoModalPopup,showModalBottomSheet,showBottomSheet) for verifying halo containment across every overlay variant. - Added:
Testing → Glass widgets modal halo test— same 4-sheet matrix againstCNPopupMenuButton,CNGlassButtonGroup,LiquidGlassContainer,CNSearchBar,CNFloatingIsland. - Updated:
Stack+Positioned tab barandSplit-search clip reproscreens now include all 4 sheet types for regression coverage. - Added:
DefaultMaterialLocalizations.delegateto the rootCupertinoAppso demos can mixshowModalBottomSheet(Material) with Cupertino routes without addingflutter_localizations.
Behavioural details #
- At rest, glass widgets render the full iOS 26 Liquid Glass capsule (including the soft-edge glow that extends slightly beyond the view's layer bounds) and stretch to fill bounded parent frames. This matches native iOS behaviour.
- During a route transition or while a modal/sheet/popup/dialog is above the widget's route, the native container is clipped and layer shadows are suppressed — the visible change is essentially invisible (the widget's visible frame is unchanged), but Flutter snapshots of the outgoing/incoming page no longer include a halo that extends past the platform-view bounds.
CNTabBarwithoutsearchItemstill uses the narrow Sheet-onlymodalDepthheuristic for its auto-hide (avoids the recreate-and-restore flash on quick action-sheet popups).CNTabBarwithsearchItemuses the broaderanyModalDepthbecause its container can't be clipped (the floating search orb needs to render above the bar's top edge).
Pana #
- 160/160
1.4.2 #
New #
-
CNTabBarRouteObserver— aNavigatorObserverthat letsCNTabBarauto-hide while a full-screen sheet is presented over its route. Resolves Issue #31 (MaterialTextFieldinvisible insideshowCupertinoSheetwhenCNTabBaris in the bottom nav slot).The native
UITabBaris rendered inside a FlutterUiKitView. When a Flutter-rendered sheet route is presented over the same navigator, hybrid composition can leave the tab bar's UIView at a higher z-index than the modal's Flutter content — makingTextFields inside the sheet invisible and letting the bar bleed through during sheet drags. Auto-hide swaps the platform view for an empty placeholder while the sheet is up, mirroring what iOS does natively when aUITabBarControllerpresents a full-screen modal.Setup (one line per app):
CupertinoApp( navigatorObservers: [CNTabBarRouteObserver()], // ... )Or
MaterialApp(navigatorObservers: [CNTabBarRouteObserver()], ...). Without this observer registered,CNTabBarstill renders correctly — it just won't auto-hide on top of sheets and you may hit the Issue #31 z-order glitch. -
CNTabBar(autoHideOnModal: bool = true)— opt-out for the auto-hide behaviour. Defaulttrue. Setfalseto keep the tab bar visible behind sheets (rare; typically requires a native sheet that won't trigger the z-order issue).
Bug Fixes #
- Fixed: tab bar's selected index resetting to 0 after a modal/sheet closed and the platform view was recreated (Issue #2 page repro).
- Root cause: in
_onCreatedwe calledrefreshbeforesetSelectedIndex. The nativerefreshmethod (a workaround for the 5-item-label-rendering bug Issue #6) capturesbar.selectedItemat start, cycles through items asynchronously, then "restores" the captured value — overriding thesetSelectedIndex(currentIndex)we sent right after, leaving the bar stuck at the stalecreationParams.selectedIndex = 0. - Fix: swapped the order —
setSelectedIndexnow runs BEFORErefresh. Refresh then captures the correct index and restores to it. Applied to both the 50ms and 200ms recreation passes.
- Root cause: in
Behavioural details #
- Auto-hide is intentionally narrow: it triggers only for routes whose runtime type name contains
Sheet(CupertinoSheetRoute,ModalBottomSheetRoute). Action-sheet popups (CupertinoModalPopupRoute), dialogs, and regular page pushes do NOT trigger auto-hide. This avoids a visible "platform view recreate + index restore" jump animation on quick popups, while still fixing the z-order issue for full-screen sheets.
Example app #
- Added:
Testing → #31: TextField — NO search variant (hypothesis test)— same flow as the Issue #31 reproduction but withCNTabBarconfigured withoutsearchItemandautoHideOnModal: false, used to verify the bug isn't search-specific. - Added: registered
CNTabBarRouteObserver()on the example app'sCupertinoAppso all demo screens benefit from auto-hide.
Pana #
- 160/160
1.4.1 #
Bug Fixes #
- Fixed:
CNTabBariOS 26 Liquid Glass selection pill was being cropped at its top edge after the v1.4.0 Issue #2 fix.- Root cause: v1.4.0 clipped the platform-view container to block the Liquid Glass drop shadow from bleeding over modal bottom sheets. The same clip also cut off the selection pill, which extends ~12–14pt above the bar's top during its morphing animation between tabs.
- Resolution: the container still clips (shadow containment preserved), but the UITabBar is now positioned 14pt below the container's top edge, and the reported intrinsic height is bar-height + 14pt. The Liquid Glass selection pill — including its morph animation when rapidly switching tabs — renders fully inside the clipped container. Bar's visible position is unchanged at the bottom of the allocated space.
- Applied to all 5 layout sites: single-bar init, split-bar init, and the equivalent setLayout rebuilds, for both iOS 26+ and iOS < 26 code paths.
Example app #
- Added:
Testing → #33: SVG in CNTabBar— reproduction screen mirroring the SVG-icons-in-CNTabBar pattern reported in Issue #33, including the reporter'sNavBarItemwrapper,iconSize: 24, andtintconfiguration. Local iOS 26 verification shows SVGs render correctly; the screen is published so the reporter (and future users hitting the same symptom) can confirm on their own setup. - Added:
Testing → Stack+Positioned tab bar— demonstrates theStack+Positioned(bottom: 0)layout pattern as an alternative toScaffold.bottomNavigationBarfor users who need custom z-order control. - Enhanced:
Testing → CNTabBar split-search clip— bright teal background and a modal-bottom-sheet trigger button so both the search-orb top-edge clip and the Issue #2 shadow-bleed scenarios can be verified side-by-side on one screen. - Bumped: example app iOS deployment target from 14.0 to 15.0 (required by the plugin's
s.platform = :ios, '15.0').
Known issues #
- iOS simulator (not real device): iOS 26 Liquid Glass rendering on the simulator is software-rasterized and has visible differences from real Metal hardware. You may see the Liquid Glass selection pill appear slightly clipped at the top, or a brief rectangular outline around buttons on press. These artifacts do not appear on real iOS 26 devices. Always verify Liquid Glass behavior on a real iPhone/iPad before treating a visual quirk as a package bug.
Pana #
- 160/160
1.4.0 #
Bug Fixes #
-
Fixed:
CNTabBartop-edge shadow bleeding over modals / bottom sheets — the regression of Issue #2 that landed between v1.3.0 and v1.3.8 (Issue #2)- Root cause: in v1.3.3 the
clipsToBounds = truecontainment from the original v1.3.0 fix was made conditional and disabled on iOS 26+. That removed the only thing keeping the UITabBar's top-edge hairline inside the platform view's bounds. container.clipsToBounds = truerestored unconditionally on the regular tab-bar platform view (5 sites — single-bar and split-bar in bothinitandsetLayout)- Added
bar.shadowImage = UIImage()on everyUITabBarinstance as belt-and-suspenders against iOS 26 ignoring the appearance-level shadow override
- Root cause: in v1.3.3 the
-
Fixed: Liquid Glass halo rendering outside platform-view bounds during iOS route transitions — the "placeholder square" reported across CNButton, CNTabBar, and other widgets (Issue #29)
- Root cause: iOS 26 Liquid Glass effects (
UIButton.Configuration.glass(),UITabBarglass material,.glassEffect()SwiftUI modifier) render a translucent halo that extends slightly outside the view's frame. Without containment, that halo became visible during route transitions as a square outline around the widget on the outgoing page. - Same containment pattern as Issue #2 applied to:
CNButton,CNPopupMenuButton,CNSearchBar,CNFloatingIsland,CNLiquidGlassContainer container.clipsToBounds = true,container.layer.shadowOpacity = 0,container.layer.backgroundColor = clear,container.isOpaque = falseplus the same on the inner subview where applicable
- Root cause: iOS 26 Liquid Glass effects (
-
Fixed:
CNTabBarwithsearchItem— the floating Liquid Glass search orb's top edge was being cropped (commented in Issue #31 by @el2zay)- The iOS 26+ search-tab-bar variant (
CupertinoTabBarSearchPlatformView) now leaves its container un-clipped so the search orb can render its top edge correctly. Top-edge hairline is still suppressed viabar.shadowImage = UIImage()andbar.layer.shadowOpacity = 0, so the original Issue #2 shadow bleed does not return.
- The iOS 26+ search-tab-bar variant (
-
Fixed:
CNGlassButtonGroupbadge X-position — the last badge floated near the screen edge instead of sitting on its button when buttons were centered as a tight pill inside a wider containerupdateBadgePositions()now estimates each button's rendered width from icon size + padding + minHeight (capsule width = max(intrinsic, minHeight)), computes the centered-HStack starting offset, and places each badge at the actual button's top-right corner instead of dividing container width evenly across button count.
-
Fixed:
CNGlassButtonGroupAuto Layout_UITemporaryLayoutWidth = 0warning on initial mount — silenced by lowering hosting-view constraint priorities to.defaultHighso UIKit can break them silently during the brief temp-width=0 phase without logging.
Test demos added #
Testing → #2: Modal bottom sheet shadow— opens aCupertinoModalPopupover aCNTabBarso the top-edge shadow bleed (or its absence) is easy to inspectTesting → #29: Per-widget halo test— one slow-transition push per widget so each can be verified in isolationTesting → CNTabBar split-search clip—CNTabBarwith asearchItemso the floating orb is easy to inspect at the bottom-rightTesting → #31: TextField disappear in modal— MaterialScaffold+CNTabBar(withsearchItem) inbottomNavigationBar, opens a modal sheet with a MaterialTextFieldand aCupertinoTextFieldfor comparison
Pana #
- 160/160
1.3.9 #
New Features #
- Added:
checkedproperty onCNPopupMenuItemfor checkmark/selected state (Issue #28)- Native iOS uses
UIAction.state = .onfor native checkmark display - Supports single-selection, multi-selection, and mixed checked+disabled states
- Flutter fallback shows a checkmark icon before the label
- Native iOS uses
Bug Fixes #
- Fixed:
PlatformException(recreating_view)on iOS hot restart (PR #30 by @lucakramberger)- New
PlatformViewGuardutility delays platform view creation during startup CNTabBarrefactored from nested FutureBuilders to state-managed async pipeline- Native
deinitcleanup added to tab bar platform views
- New
1.3.8 #
Bug Fixes #
- Fixed: macOS build — resolved 5 compilation errors in native Swift code
badgeCountparameter missing fromsetupSwiftUIButtonmethod.clearcolor inference onCALayer.backgroundColor(now usesNSColor.clear.cgColor)FlutterPlatformViewprotocol replaced withNSViewfor LiquidGlassContainer- Removed invalid
namespaceargument fromGlassButtonSwiftUIcall NSButton.titlenon-optional handling
1.3.7 #
New Features #
- Added: Popup menu button support in
CNGlassButtonGroupviaCNButtonData.popup()(PR #23 by @byackee)- Mix regular icon buttons and popup menu buttons in the same glass button group
- Native SwiftUI rendering with
UIMenusupport CNButtonDataPopupItemmodel for popup menu items
- Added:
labelFontFamilyandlabelFontSizeproperties forCNTabBar(PR #26, Issue #16 by @byackee)- Customize tab bar label font with any registered font family
- Dynamic font updates via method channel
Bug Fixes #
- Fixed:
buttonCustomIconColornow works on iOS 26 with Liquid Glass rendering (PR #24, Issue #21 by @byackee)- Color is now sent to the native side via
capturedButtonIconColor - Native side applies
.withTintColor(.alwaysOriginal)to preserve custom icon colors - Menu item
iconColoralso supported for customIconDataicons
- Color is now sent to the native side via
- Fixed:
CNSwitchno longer pushed upward by keyboard (PR #25, Issue #4 by @byackee)- iOS 16.4+: uses
safeAreaRegions.remove(.keyboard)official API - Pre-iOS 16.4: runtime fix targeting the hosting view's private keyboard notification handler
- iOS 16.4+: uses
1.3.6 #
Bug Fixes #
- Fixed: Horizontal glass button group "waist" effect — reduced toolbar shrinkage between adjacent buttons by enforcing minimum 80pt glass spacing for horizontal groups with 2+ buttons (PR #20 by @byackee)
- Fixed:
CNTabBarnow shows a Flutter fallback tab bar while the native view initializes, instead of blank space for ~2 seconds (Issue #5) - Fixed:
CNTabBarwith 5 items no longer has sporadic missing labels — added a second refresh pass for slow-to-initialize native views (Issue #6)
Improvements #
- Added: macOS podspec for CocoaPods support (Issue #10)
1.3.5 #
Bug Fixes #
- Fixed:
CNTabBariconSizenow correctly applies toCNImageAsset(SVG/image) icons (Issue #19)- Previously, only SF Symbol icons respected the
iconSizeproperty - Image assets loaded via
loadFlutterAssetandcreateImageFromDatanow receive the size parameter
- Previously, only SF Symbol icons respected the
1.3.4 #
New Features #
- Added:
interactionproperty forCNButtonConfigandCNButtonDataConfig(PR #15 by @anirudhrao-github)- Allows disabling button touch handling without changing visual appearance
- When
interaction: false, button maintains normal look but doesn't respond to touches - Useful for conditional interactivity while preserving UI consistency
Improvements #
- Improved:
LiquidGlassContainerlayout simplified for better parent alignment control
1.3.3 #
New Features #
-
Added:
customIconSizeproperty forCNButtonConfigandCNButtonDataConfig(PR #12 by @anirudhrao-github)- Allows customizing the size of custom icons (IconData) in buttons
- Previously hardcoded to 20.0 points, now configurable
-
Added:
iconSizeproperty forCNTabBarto control SF Symbol icon sizes- Supports dynamic icon sizing with automatic height adjustment
- Note: Icons above 30pt may have minor visual quirks due to UITabBar constraints
Bug Fixes #
-
Fixed:
CNGlassButtonGroupno longer forces equal width on all buttons (PR #12 by @anirudhrao-github)- Buttons now use their intrinsic width based on content
- Label buttons can now be wider than icon-only buttons in the same group
- Uses SwiftUI
.fixedSize(horizontal: true, vertical: false)for proper sizing
-
Fixed:
CNTabBar.onTapnow fires for reselects (Issue #13)- Previously, tapping the already-selected tab did not trigger the callback
- Now all taps fire
onTap, allowing scroll-to-top or navigation reset on reselect
-
Fixed:
CNTabBaricon clipping on iOS 26+ Liquid Glass- Disabled
clipsToBoundson iOS 26+ to allow proper Liquid Glass pill overflow - Tab bar height now adjusts dynamically based on icon size
- Disabled
Improvements #
- Improved: Initial layout rendering for
CNGlassButtonGroup- Added immediate layout pass after view creation for correct first render
1.3.2 #
New Features #
- Added: Badge support for
CNGlassButtonGroupicon buttons (PR #11 by @anirudhrao-github)- New
badgeCountproperty onCNButtonData.icon()for displaying notification badges - Badges display as red circles with white text, showing "99+" for counts over 99
- Uses UIKit overlay on iOS to prevent glass effect sampling artifacts
- Proper clipping during page transitions
- New
Improvements #
-
Improved: Added library-level documentation for better API discoverability
- Enhanced dartdoc comments for
button,button_data,button_style, andcupertino_nativelibraries - 91.4% API documentation coverage
- Enhanced dartdoc comments for
-
Fixed: Dart formatting issues for pub.dev compliance
- Resolved formatting in
button.dartandglass_button_group.dart - Achieves 160/160 pana score
- Resolved formatting in
1.3.1 #
Bug Fixes #
- Fixed: Tint color now works correctly when buttons are inside
CNGlassButtonGroup(PR #8 by @anirudhrao-github)- Previously, button tint colors were ignored when placed inside grouped glass buttons
- Now buttons properly inherit and display their configured tint colors within button groups
1.3.0 #
New Features #
-
Added:
CNTabBarNative- Native iOS 26 Tab Bar with full UITabBarController integration- Uses native
UITabBarController+UISearchControllerfor authentic iOS 26 liquid glass effects CNTabBarNative.enable()/CNTabBarNative.disable()for app-level tab bar managementCNTabclass for tab configuration with SF Symbols and search tab support- Callbacks:
onTabSelected,onSearchChanged,onSearchSubmitted,onSearchCancelled,onSearchActiveChanged - Full badge count support and dynamic styling
- Uses native
-
Added:
CNSearchScaffold- Native search scaffold controller for standalone search UI -
Added:
CNToast- Toast notification widget with Liquid Glass effects- Static methods:
show(),success(),error(),warning(),info(),loading() - Duration presets: short (2s), medium (3.5s), long (5s)
- Position options: top, center, bottom
- Auto-dismiss with queue management
CNLoadingToastHandlefor dismissing loading toasts
- Static methods:
-
Added:
labelproperty toCNTabBarSearchItemfor customizing the search tab label- Defaults to 'Search' to match iOS native behavior
-
Added:
preserveTopToBottomOrderproperty toCNPopupMenuButton(Issue #3)- When
true, menu items maintain top-to-bottom order (1,2,3,4) regardless of menu direction - Default
falsepreserves native iOS behavior where item 1 stays closest to the button - Uses
UIDeferredMenuElement.uncachedfor dynamic position detection
- When
Improvements #
-
Enhanced:
PlatformVersionnow auto-initializes on first access- No longer need to call
await PlatformVersion.initialize()inmain() - Just use
PlatformVersion.isIOS26OrLaterdirectly - Old
initialize()method kept for backwards compatibility (marked deprecated)
- No longer need to call
-
Added: New helper properties to
PlatformVersion:isIOS,isMacOS,isAndroid,isAppleisIOSVersionInRange(min, max),isMacOSVersionInRange(min, max)
Bug Fixes #
-
Fixed:
CNPopupMenuButton.iconnow respects the order defined in items (Issue #3)- Added
preserveTopToBottomOrderparameter to control item ordering behavior - Native iOS behavior keeps first item closest to button; set
preserveTopToBottomOrder: truefor consistent top-to-bottom order
- Added
-
Fixed: Tab bar shadow artifact appearing over modals and bottom sheets (Issue #2)
- Changed
configureWithDefaultBackground()toconfigureWithTransparentBackground() - Added explicit shadow removal:
shadowColor = .clear,shadowImage = UIImage() - Added
container.clipsToBounds = trueandlayer.shadowOpacity = 0
- Changed
-
Fixed: Search bar keyboard auto-opening behavior (Issue #1)
automaticallyActivatesSearch: falsenow properly prevents keyboard from auto-opening- This is native iOS behavior - the search bar expands but keyboard only opens on text field tap
1.2.0 #
New Features #
-
Added: iOS 26 Search Tab Feature for CNTabBar with animated Liquid Glass expansion
- Native
UISearchTab-style search integration that follows Apple's iOS 26 design - Search button expands into a full search bar with smooth spring animation
- Tabs collapse to icon-only mode when search is active
- Full Flutter fallback for iOS < 26 with identical behavior
- Native
-
Added:
CNTabBarSearchItemconfiguration class for search tab customizationplaceholder: Custom placeholder text for the search fieldonSearchChanged: Callback for live filtering as user typesonSearchSubmit: Callback when user submits searchonSearchActiveChanged: Callback for expand/collapse state changesautomaticallyActivatesSearch: Control keyboard auto-activation behavior
-
Added:
CNTabBarSearchStylefor visual customization- Icon sizes, colors, and active states
- Search bar dimensions, padding, and border radius
- Animation duration control
- Clear button visibility toggle
-
Added:
CNTabBarSearchControllerfor programmatic search controlactivateSearch()/deactivateSearch(): Expand/collapse search programmaticallytextproperty: Get/set search textclear(): Clear search text with optional deactivation- Listener support for reactive state management
Improvements #
- Enhanced:
automaticallyActivatesSearchnow properly controls keyboard behavior- When
false: Search bar expands but keyboard only opens when user taps the text field - When
true(default): Keyboard opens automatically when search expands - Mirrors
UISearchTab.automaticallyActivatesSearchfrom UIKit
- When
Bug Fixes #
- Fixed:
MissingPluginExceptionerrors during hot reload forsetItemsandrefreshmethods- Added try-catch error handling to prevent crashes during development
- Search view now handles all expected method channel calls
1.1.9 #
New Features #
- Added: Lightweight
setBadgesmethod for CNTabBar to update badge values without rebuilding the entire tab bar- Previously, badge updates required recreating all tab bar items which caused visible flicker
- New implementation only updates
badgeValueon existing UITabBarItems for smooth, instant badge changes - Automatically detected when only badges changed (not labels, icons, or symbols) and uses fast path
Improvements #
- Optimized: CNTabBar now detects badge-only updates in
_syncPropsToNativeIfNeeded()and calls lightweight nativesetBadgesmethod instead of fullsetItemsrebuild - Performance: Badge updates are now instant with no view recreation or animation interruption
1.1.7 #
Fixes #
-
Fixed: Split mode tab selection bug where the wrong tab appeared selected on first load
- Issue: When using
split: truein CNTabBar, the right bar (e.g., Rewards tab) would incorrectly appear selected even when the left bar tab (e.g., Discover) was actually selected - Root Cause: In the
refreshmethod, when restoring selection after cycling through tabs for label rendering, the code was incorrectly settingright.selectedItem = rightItems.firstwhenrightOriginalwas nil - Solution: Changed to restore the original selection directly (
right.selectedItem = rightOriginal), which correctly keeps the right bar unselected when a left bar tab is active
- Issue: When using
-
Fixed: Added
setSelectedIndexcall afterrefreshin Flutter widget to ensure correct selection state after view initialization
1.1.5 #
Breaking Changes #
- iOS Minimum Version: Raised iOS deployment target from 13.0 to 15.0
- Required for
@FocusStateand other iOS 15+ SwiftUI features - Most production apps already target iOS 15+ (released September 2021)
- Required for
Fixes #
- Fixed: Swift compiler error
'FocusState' is only available in iOS 15.0 or newer - Fixed: Swift compiler error
'self' used before 'super.init' callin CNSearchBar - Fixed: Pod installation issues when used in projects with iOS 15+ deployment target
1.1.3 #
Fixes #
- Fixed: Full 50/50 pub.dev static analysis score (160/160 pana points)
- Fixed: All remaining lint and formatting issues
1.1.0 #
Documentation Overhaul #
- Added: Complete documentation for all widgets with real iOS 26 screenshots
- Added: CNSwitch documentation with controller examples
- Added: CNPopupMenuButton documentation with text and icon variants
- Added: CNSegmentedControl documentation with SF Symbols support
- Added: Button Styles Gallery showcasing multiple button styles
- Added: Popup menu opened state preview image
- Enhanced: Features table with Controller column
- Enhanced: All images now use centered alignment for better presentation
New Screenshots #
- Real iOS 26 Liquid Glass component screenshots (replacing AI-generated placeholders)
- Button styles gallery (4 preview images)
- Switch, Slider, Popup Menu, Segmented Control, Tab Bar previews
- Popup menu opened state preview
Test Suite Updates #
- Added: Comprehensive widget tests for CNSearchBar, CNFloatingIsland, CNGlassButtonGroup
- Added: Controller tests for CNSearchBarController, CNFloatingIslandController, CNSliderController
- Added: Data model tests for CNButtonData, CNButtonDataConfig, CNSymbol, CNImageAsset
- Updated: Platform and method channel tests with error handling and null response tests
- Updated: Enum tests for all new enums (CNGlassEffect, CNGlassEffectShape, CNSpotlightMode, etc.)
- Total: 82 tests covering all major components and APIs
1.0.6 #
Improvements #
- Fixed: Dart formatting issues to achieve full 50/50 static analysis score on pub.dev
- Added: Preview image for pub.dev package page
1.0.5 #
Improvements #
Static Analysis Cleanup
- Fixed: All
use_build_context_synchronouslywarnings by capturing context-derived values before async gaps - Fixed:
dangling_library_doc_commentswarning - Fixed:
unnecessary_library_nameandunnecessary_importwarnings - Improved: Pub points score (static analysis section)
1.0.4 #
Bug Fixes #
CNButton Tap Detection (iOS < 26 Fallback)
- Fixed: Unreliable tap detection in CupertinoButton fallback mode
- Issue: Buttons showed press animation but
onPresseddidn't fire consistently - Solution: Added
minSize: 0to prevent CupertinoButton's internal minimum size from conflicting with SizedBox constraints - Added: Explicit
borderRadiusandpressedOpacityfor better hit testing and visual feedback
1.0.3 #
Bug Fixes #
Critical: iOS 18 Crash Fix
- Fixed: Reverted GestureDetector overlay that caused crash on iOS 18
- Error:
unrecognized selector sent to instance 'onTap:' - Solution: Removed Stack/GestureDetector approach, kept simple CupertinoButton
Icon Button Padding (kept from 1.0.2)
- Fixed: Increased default padding for icon buttons from 4 to 8 pixels
1.0.2 (BROKEN - DO NOT USE) #
Bug Fixes #
CNButton Tap Detection (iOS < 26 Fallback)
- BROKEN: Added GestureDetector overlay that crashed on iOS 18
- Use 1.0.3 instead
Icon Button Padding
- Fixed: Increased default padding for icon buttons from 4 to 8 pixels
- Icons now have proper breathing room from the button border
1.0.1 #
- Pub Points Improvement: Addressed static analysis issues to improve package score.
- Fix: Resolved
use_build_context_synchronouslywarnings across multiple components. - Fix: Replaced deprecated
Color.valueandwithOpacityusages with modern alternatives. - Documentation: Added missing documentation for public members.
1.0.0 #
Major Release - Complete iOS Fallback Fixes
This release addresses critical issues that caused components to malfunction on iOS versions below 26.
Breaking Changes #
- Package renamed from
cupertino_native_plustocupertino_native_better - Main import changed to
package:cupertino_native_better/cupertino_native_better.dart
Bug Fixes #
CNButton Label Disappearing (iOS < 26)
- Fixed: Buttons with both icon AND label now correctly display both elements in fallback mode
- Root Cause:
widget.isIconwas returningtruefor any button with an icon, even if it also had a label - Solution: Changed fallback check to
widget.isIcon && widget.label == nullto only treat truly icon-only buttons as icon-only
CNTabBar Icons Not Showing (iOS < 26)
- Fixed: Tab bar icons now render correctly using CNIcon instead of empty placeholder circles
- Root Cause: Fallback code only checked for
customIcon, ignoring SF Symbols (icon/activeIcon) - Solution: Added
_buildTabIcon()helper that properly handles all icon types with correct priority
CNIcon/CNButton/CNPopupMenuButton Showing "..." (iOS < 26)
- Fixed: All CN components now properly render SF Symbols on older iOS versions
- Root Cause: Components were checking
shouldUseNativeGlass(iOS 26+) for SF Symbol support, but SF Symbols work on iOS 13+ - Solution: Added new
supportsSFSymbolsgetter that always returns true on iOS/macOS
New Features #
- Added
PlatformVersion.supportsSFSymbolsfor checking SF Symbol availability (iOS 13+, macOS 11+) - Comprehensive dartdoc documentation for all public APIs
- Full comparison table with other packages in README
Documentation #
- Complete rewrite of README with feature comparison
- Migration guide from cupertino_native_plus
- Comprehensive code examples for all widgets
0.0.9 #
- Package preparation for public release
- Updated repository URLs
0.0.8 #
- Fixed SF Symbol rendering in fallback mode for CNButton
- Fixed SF Symbol rendering in fallback mode for CNPopupMenuButton
- Added proper imports for CNIcon in button and popup components
0.0.7 #
- Added
supportsSFSymbolsgetter to PlatformVersion - SF Symbols now render natively on all iOS versions (13+), not just iOS 26+
- Separated Liquid Glass support (iOS 26+) from SF Symbol support (iOS 13+)
0.0.6 #
- Dark Mode Support for LiquidGlassContainer: Added automatic dark mode detection and synchronization for LiquidGlassContainer, ensuring the glass effect correctly adapts to Flutter's theme changes
- Gesture Detection Fixes: Fixed gesture handling in LiquidGlassContainer by wrapping platform views in IgnorePointer, preventing the native view from intercepting touch events and allowing child widgets to receive gestures properly
- Brightness Syncing Improvements: Enhanced brightness synchronization for icons and other components, ensuring they automatically update when the system theme changes
0.0.5 #
- Performance Improvements: Added method channel updates for button groups to prevent full rebuilds and eliminate freezes when updating button parameters
- Preserved Animations: Button groups now update smoothly without losing native animations when button properties change (icon, color, image asset, etc.)
- Efficient Updates: Implemented granular updates for individual buttons in groups, only updating changed buttons instead of rebuilding the entire group
- Reactive SwiftUI Updates: Converted button group SwiftUI views to use ObservableObject pattern for efficient reactive updates
- Button Parameter Updates: Individual buttons in groups can now be updated dynamically via method channels without full view rebuilds
0.0.4 #
- PNG Image Support: Added full support for PNG images in all components (buttons, icons, popup menus, tab bars, glass button groups)
- Automatic Asset Resolution: Implemented automatic asset resolution based on device pixel ratio, similar to Flutter's automatic asset selection. The system now automatically selects the appropriate resolution-specific asset (e.g.,
assets/icons/3.0x/checkcircle.pngfor @3x devices) or falls back to the closest bigger size - ImageUtils Consolidation: Consolidated all image loading, format detection, scaling, and tinting logic into a shared
ImageUtils.swiftclass for better code maintainability and consistency - Fixed PNG Rendering: Fixed PNG image rendering issues in buttons and glass button groups
- Fixed Image Orientation: Fixed image flipping issues for both PNG and SVG images when colors are applied
- Made buttonIcon Optional: Made
buttonIconparameter optional inCNPopupMenuButton.iconconstructor, allowing developers to use onlybuttonImageAssetorbuttonCustomIcon - Improved Glass Effect Appearance: Fixed glass effect appearance synchronization with Flutter's theme mode to prevent dark-to-light transitions on initial render
- Enhanced Image Format Detection: Improved automatic image format detection from file extensions and magic bytes
- Better Fallback Handling: Improved fallback behavior when asset paths fail to load, ensuring images still render from provided image bytes
0.0.3 #
- Updated README to showcase all icon types (SVG assets, custom icons, and SF Symbols)
- Added comprehensive examples for all icon types in Button, Icon, Popup Menu Button, and Tab Bar sections
- Added icon support overview at the beginning of "What's in the package" section
- Clarified that all components support multiple icon types with unified priority system
0.0.2 #
- Updated README with corrected version requirements and improved documentation
- Fixed iOS minimum version requirement (13.0 instead of 14.0)
- Removed incorrect Xcode 26 beta requirement
- Added Contributing and License sections
- Improved package description and introduction
0.0.1 #
- Initial release
- Fixed iOS 26+ version detection using Platform.operatingSystemVersion parsing
- Native Liquid Glass widgets for iOS and macOS
- Support for CNButton, CNIcon, CNSlider, CNSwitch, CNTabBar, CNPopupMenuButton, CNSegmentedControl
- Glass effect unioning for grouped buttons
- LiquidGlassContainer for applying glass effects to any widget
