Skip to main content

RFloatingCartIndicator

A persistent, elegant cart indicator that appears on all screens when the cart contains items. Provides quick access to checkout and real-time cart updates with smooth animations.

Overview

The RFloatingCartIndicator is designed to provide users with constant awareness of their cart status and easy access to checkout from anywhere in your app. It automatically appears when items are added to the cart and disappears when the cart becomes empty.

Key Features

  • Global Persistence - Appears on every screen when cart has items
  • Real-time Updates - Shows current item count and total price
  • Quick Checkout Access - One-tap to open checkout overlay
  • Elegant Design - Gradient background with professional styling
  • Smart Animations - Bounce effect when items are added
  • Auto-hide - Disappears automatically when cart is empty
  • Haptic Feedback - Tactile confirmation on iOS devices
  • Cross-platform - Works on iOS, macOS, tvOS, and watchOS

Basic Usage

Simple Integration

Add the floating cart indicator to your main content view:

ContentView.swift
import SwiftUI
import ReachuUI

struct ContentView: View {
@EnvironmentObject var cartManager: CartManager

var body: some View {
NavigationView {
// Your main app content
ProductCatalogView()
}
.overlay {
RFloatingCartIndicator()
.environmentObject(cartManager)
}
.sheet(isPresented: $cartManager.isCheckoutPresented) {
RCheckoutOverlay()
.environmentObject(cartManager)
}
}
}

What You Get Automatically

When you add RFloatingCartIndicator to your app:

  1. Cart appears when first item is added
  2. Count updates in real-time as items are added/removed
  3. Price updates automatically when quantities change
  4. Bounce animation plays when new items are added
  5. Tapping opens the checkout overlay immediately
  6. Cart disappears when all items are removed

Design & Layout

Visual Design

The floating cart indicator features:

  • Gradient Background - Primary color gradient for brand consistency
  • Rounded Corners - Capsule shape for modern appearance
  • Shadow - Subtle drop shadow for depth
  • Badge - White circular badge with item count
  • Typography - Clear, readable text with proper hierarchy

Positioning

The indicator automatically positions itself:

  • Bottom Center - Centered horizontally at the bottom of the screen
  • Safe Area Aware - Respects device safe areas and navigation bars
  • Consistent Margin - Maintains proper spacing from screen edges
  • Above Content - Appears above your app content without interference

Size & Spacing

Design Specifications
// Container
.padding(.horizontal, ReachuSpacing.lg) // 24pt horizontal padding
.padding(.vertical, ReachuSpacing.md) // 16pt vertical padding
.padding(.bottom, ReachuSpacing.xl) // 32pt bottom margin

// Internal spacing
HStack(spacing: ReachuSpacing.sm) // 12pt between elements

// Badge positioning
.offset(x: 12, y: -8) // Positioned on cart icon

Integration Examples

With Tab Bar Apps

TabBarApp.swift
struct TabBarApp: View {
@EnvironmentObject var cartManager: CartManager

var body: some View {
TabView {
ProductsView()
.tabItem {
Image(systemName: "bag.fill")
Text("Products")
}

CartView()
.tabItem {
Image(systemName: "cart.fill")
Text("Cart")
}
// Automatic cart badge on tab
.badge(cartManager.itemCount > 0 ? cartManager.itemCount : nil)
}
// Floating cart works with tab bars
.overlay {
RFloatingCartIndicator()
.environmentObject(cartManager)
}
.sheet(isPresented: $cartManager.isCheckoutPresented) {
RCheckoutOverlay()
.environmentObject(cartManager)
}
}
}

With Navigation Stack

NavigationApp.swift
struct NavigationApp: View {
@EnvironmentObject var cartManager: CartManager

var body: some View {
NavigationStack {
ProductListView()
.navigationTitle("Products")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
// Optional: Additional cart button in navigation
Button {
cartManager.showCheckout()
} label: {
Image(systemName: "cart")
.overlay(
cartManager.itemCount > 0 ?
Badge(count: cartManager.itemCount) : nil
)
}
}
}
}
// Floating cart complements navigation
.overlay {
RFloatingCartIndicator()
.environmentObject(cartManager)
}
}
}

Multiple Screen Integration

The floating cart automatically works across all your app screens:

Multi-Screen Example
// Product Catalog Screen
ProductCatalogView()
.overlay { RFloatingCartIndicator() } // ✅ Shows cart

// Product Detail Screen
ProductDetailView(product: product)
.overlay { RFloatingCartIndicator() } // ✅ Shows cart

// Search Results Screen
SearchResultsView(query: searchQuery)
.overlay { RFloatingCartIndicator() } // ✅ Shows cart

// User Profile Screen
UserProfileView()
.overlay { RFloatingCartIndicator() } // ✅ Shows cart

// Any other screen in your app
AnyView()
.overlay { RFloatingCartIndicator() } // ✅ Shows cart

Advanced Customization

Custom Checkout Actions

While the floating cart automatically opens the checkout overlay, you can customize the behavior:

Custom Checkout Behavior
struct CustomFloatingCartExample: View {
@EnvironmentObject var cartManager: CartManager
@State private var showCustomCheckout = false

var body: some View {
YourContentView()
.overlay {
// Use the standard floating cart
RFloatingCartIndicator()
.environmentObject(cartManager)
}
// Custom checkout flow
.sheet(isPresented: $cartManager.isCheckoutPresented) {
CustomCheckoutFlow()
.environmentObject(cartManager)
}
}
}

Conditional Display

You can conditionally show the floating cart based on app state:

Conditional Display
struct ConditionalCartExample: View {
@EnvironmentObject var cartManager: CartManager
@State private var isCheckoutAllowed = true

var body: some View {
YourContentView()
.overlay {
// Only show floating cart when checkout is allowed
if isCheckoutAllowed {
RFloatingCartIndicator()
.environmentObject(cartManager)
}
}
}
}

Animation Details

Bounce Animation

When items are added to the cart, the floating cart plays a satisfying bounce animation:

Animation Specifications
// Badge bounce when items added
.scaleEffect(bounceAnimation ? 1.2 : 1.0)
.animation(.spring(response: 0.3, dampingFraction: 0.6), value: bounceAnimation)

// Appears/disappears smoothly
.animation(.spring(response: 0.6, dampingFraction: 0.8), value: cartManager.itemCount)

Press Animation

When users tap the floating cart:

Press Feedback
// Scale down on press
.scaleEffect(isPressed ? 0.95 : 1.0)
.animation(.easeInOut(duration: 0.1), value: isPressed)

// Haptic feedback on iOS
#if os(iOS)
let impactFeedback = UIImpactFeedbackGenerator(style: .medium)
impactFeedback.impactOccurred()
#endif

Accessibility

The floating cart includes comprehensive accessibility support:

Accessibility Features
// Automatic accessibility label
.accessibilityLabel("Shopping cart with \(cartManager.itemCount) items, total \(cartManager.currency) \(cartManager.cartTotal)")

// Action hint
.accessibilityHint("Tap to open checkout")

// Cart count value
.accessibilityValue("\(cartManager.itemCount) items")

// Role identification
.accessibilityAddTraits(.isButton)

Performance Considerations

Efficient Updates

The floating cart is optimized for performance:

  • Reactive Updates - Only redraws when cart state changes
  • Minimal Layout - Simple HStack with efficient text rendering
  • Conditional Rendering - Only appears when needed
  • Animation Optimization - Uses hardware-accelerated animations

Memory Management

  • Automatic Cleanup - Disposes resources when cart is empty
  • Observer Pattern - Uses @EnvironmentObject for efficient updates
  • Animation Disposal - Properly cancels animations when view disappears

Best Practices

Integration Guidelines

  1. Use Globally - Add to your main app container for global access
  2. Combine with Checkout - Always pair with RCheckoutOverlay
  3. Respect Safe Areas - The component automatically handles safe areas
  4. Test on Devices - Verify positioning on different screen sizes

Design Considerations

  1. Brand Consistency - Uses your app's primary colors automatically
  2. Accessibility First - Includes comprehensive accessibility support
  3. Cross-Platform - Works consistently across all Apple platforms
  4. Performance - Optimized for smooth animations and efficient rendering

User Experience

  1. Predictable Behavior - Appears/disappears based on cart state
  2. Clear Feedback - Shows exact count and total price
  3. Quick Access - One-tap to checkout from anywhere
  4. Non-Intrusive - Doesn't interfere with app navigation

Platform-Specific Notes

iOS

  • Full haptic feedback support
  • Respects Dynamic Type for text sizing
  • Works with all screen sizes including iPhone and iPad

macOS

  • Adapted for cursor interaction
  • Proper hover states and click feedback
  • Respects macOS design guidelines

tvOS

  • Optimized for remote control navigation
  • Focus management compatible
  • Appropriate sizing for TV screens

watchOS

  • Simplified design for small screens
  • Essential information only
  • Optimized for Series 4+ screens

Pro Tip

The floating cart indicator works best when combined with the complete Reachu UX system. Use it alongside RToastNotification for notifications and RCheckoutOverlay for the complete checkout experience.

Integration Note

The floating cart automatically integrates with CartManager state. Simply add it to your view hierarchy and it will work seamlessly with all other Reachu components.