Contents

6639835/Toast

A production-ready iOS toast notification library

Requirements

  • iOS 17+
  • Swift 5.9+
  • Xcode 15+

Installation

Swift Package Manager

Add Toast to your Package.swift:

dependencies: [
    .package(url: "https://github.com/6639835/Toast.git", from: "1.0.0")
]

Or add it via Xcode: File → Add Package Dependencies and enter the repository URL.


Quick Start

1. Install the host modifier once at your scene root:

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .toastHost()
        }
    }
}

2. Show toasts from anywhere:

// From a view model or async action:
ToastManager.shared.show(.success, title: "Photo saved")
ToastManager.shared.show(.error, title: "Upload failed", subtitle: "Check your connection")

// From a SwiftUI view via environment:
@Environment(\.toastManager) var toastManager

Button("Save") {
    toastManager?.show(.success, title: "Saved")
}

3. Binding-driven presentation:

@State private var toast: ToastItem?

Button("Save") {
    toast = ToastItem(kind: .success, title: "Saved")
}
.toast(item: $toast)

API Reference

ToastManager

The primary entry point. One instance per UIWindowScene.

| Method | Description | |---|---| | ToastManager.shared | Convenience accessor for single-scene apps | | ToastManager.manager(for:) | Per-scene accessor for multi-scene apps | | show( kind:title:subtitle:duration:position:) | Show a toast with semantic convenience | | show( item:) | Show a fully configured ToastItem | | dismissCurrent() | Dismiss the visible toast immediately | | dismiss(id:) | Dismiss a toast by its UUID | | cancelAll() | Cancel all pending and visible toasts | | removeManager(for:) | Clean up when a scene disconnects |

ToastKind

Controls icon, haptic feedback, and default display duration.

| Case | Icon | Default Duration | |---|---|---| | .success | checkmark.circle.fill | 3s | | .info | info.circle.fill | 3s | | .warning | exclamationmark.circle.fill | 4s | | .error | xmark.circle.fill | 4s |

ToastDuration

| Value | Duration | |---|---| | .default | Kind-appropriate (see above) | | .short | 2 seconds | | .standard | 3.5 seconds | | .long | 5 seconds | | .indefinite | No auto-dismiss | | .custom(_ seconds:) | 1–8 seconds (clamped) |

ToastPosition

| Case | Description | |---|---| | .bottom | Above home indicator (default) | | .center | Vertically centered | | .top | Below status bar |

ToastItem

ToastItem(
    kind: .success,
    title: "File saved",
    subtitle: "Tap to open",          // optional
    iconName: "square.and.arrow.up",  // nil = kind default, "" = suppress icon
    duration: .standard,
    position: .bottom,
    tapToDismiss: true
)

SwiftUI Modifiers

| Modifier | Description | |---|---| | .toastHost() | Installs toast infrastructure — call once at scene root | | .toast(item:) | Presents a toast when binding becomes non-nil | | @Environment(\.toastManager) | Access the scene-bound manager from any view |


Architecture

Toast uses a UIWindowScene-backed overlay window sitting above the key window. This ensures toasts appear over sheets, full-screen covers, and navigation stacks — something pure SwiftUI overlay modifiers cannot guarantee.

A Swift actor-isolated queue serializes all enqueue, dismiss, and timer operations, eliminating concurrency bugs between auto-dismiss timers and rapid-fire enqueue events.

Key behaviors:

  • FIFO queueing — multiple toasts are shown in order, one at a time
  • Deduplication — identical consecutive toasts refresh the timer instead of stacking
  • Safe area awareness — respects Dynamic Island, home indicator, and keyboard
  • Hit-test pass-through — touches outside the toast reach your app normally
  • Accessibility — VoiceOver announcements, Reduce Motion support, semantic traits
  • HapticsUINotificationFeedbackGenerator feedback per kind

Multi-Scene Support

For apps with multiple UIWindowScene instances, use the per-scene API:

// In your SceneDelegate or scene-lifecycle handler:
let manager = ToastManager.manager(for: windowScene)
manager.show(.info, title: "Scene-specific toast")

// Clean up when the scene disconnects:
ToastManager.removeManager(for: windowScene)

License

Toast is available under the MIT license. See LICENSE for details.

Package Metadata

Repository: 6639835/Toast

Stars: 0

Forks: 0

Open issues: 0

Default branch: main

Primary language: swift

License: MIT

README: README.md