A polished, dependency-free SwiftUI toast / snackbar library.
- Queued presentation — FIFO queue, one toast at a time, automatic advance.
- Semantic styles —
.info,.success,.warning,.error, plus fully customToastStyles. - Auto-dismiss — per-toast durations (
.seconds(_:)or.infinite) with a cancellable timer. - Gestures — swipe toward the edge to dismiss, optional tap actions.
- Springy animations — move + fade insertion/removal, position-aware (
.top/.bottom). - Accessibility built in — VoiceOver announcements, Dynamic Type–friendly layout, Reduce Motion honored (crossfade instead of spring move).
- Testable by design — inject a scheduler to control time; inject
ToastCenterinstances anywhere. - Concurrency-safe —
@MainActorpresentation model,Sendablevalues, warning-free build.
File ▸ Add Package Dependencies… and enter:
https://github.com/giaBaoJS/ToastKit
dependencies:[.package(url:"https://github.com/giaBaoJS/ToastKit", from:"0.1.0")],targets:[.target(name:"MyApp", dependencies:["ToastKit"])]Attach the overlay once at the root of your hierarchy, then present from anywhere on the main actor:
import SwiftUI
import ToastKit
@mainstructMyApp:App{varbody:someScene{WindowGroup{RootView().toastKit() // uses ToastCenter.shared
}}}ToastCenter.shared.present(.success("Saved"))ToastCenter.shared.present(.error("Upload failed", title:"Network"))ToastCenter.shared.present(Toast(
message:"New version available",
title:"Update",
style:.info,
duration:.infinite,
position:.top,
onTap:{openAppStore()}))| Type | Role |
|---|---|
Toast | Value type describing one toast: message, title, style, icon override, duration, position, onTap. |
Toast.Style | .info / .success / .warning / .error / .custom(ToastStyle). |
Toast.Duration | .seconds(Double) or .infinite; defaults to 3 seconds. |
Toast.Position | .top or .bottom; controls anchor, transition edge, and swipe direction. |
ToastCenter | @MainActor ObservableObject — FIFO queue: present(_:), dismissCurrent(), dismissAll(), currentToast, pending. |
View.toastKit(center:) | Installs the rendering overlay; defaults to ToastCenter.shared. |
ToastStyle / ToastShadow | Visual theme: background, foreground, icon, corner radius, shadow. |
ToastScheduling / TaskToastScheduler | Auto-dismiss timer abstraction; inject a fake in tests. |
ToastView | The rendered toast, public for custom containers and previews. |
The four semantic styles come with sensible light/dark-friendly defaults. For
branded toasts, build a ToastStyle:
letbrand=ToastStyle(
background:Color("BrandPurple"), // asset colors adapt to dark mode
foreground:.white,
icon:"sparkles",
cornerRadius:20,
shadow:ToastShadow(color:.black.opacity(0.35), radius:14, y:6))ToastCenter.shared.present(Toast(message:"Welcome back!", style:.custom(brand)))Per-toast icon overrides keep the semantic colors but swap the symbol:
Toast(message:"Added to favorites", style:.success, icon:"star.fill")See the hosted DocC documentation
(source: Sources/ToastKit/ToastKit.docc) for the full Getting Started and
Theming articles.
- VoiceOver — each presented toast posts an announcement (title + message) on iOS; a graceful no-op on macOS.
- Dynamic Type — text uses scalable fonts with no fixed heights, so toasts grow with the user's type size.
- Reduce Motion — when enabled, the spring move transition becomes a plain crossfade.
- Rotor actions — a "Dismiss" accessibility action is exposed on every toast; tappable toasts get the button trait.
An interactive demo covering styles, positions, queueing, custom themes, icon
overrides, tap actions, and sticky toasts lives in Examples/ToastKitDemo.
brew install xcodegen # if neededcd Examples/ToastKitDemo
xcodegen generate # regenerates ToastKitDemo.xcodeproj
open ToastKitDemo.xcodeproj # run the ToastKitDemo scheme on an iOS simulatorswift build # library
swift test# unit testsToastKit is available under the MIT license. See LICENSE.
