Skip to content

codewithswiftly/ToastKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ToastKit

Lightweight, beautiful toast notifications for SwiftUI — no UIKit required.

Swift iOS SwiftUI SPM License


What is ToastKit?

ToastKit lets you show brief notification banners (toasts) anywhere in your SwiftUI app with a single line of code. No UIKit, no view controllers, no window hacks — just pure SwiftUI.

ToastManager.shared.show(.success("Profile saved!"))
ToastManager.shared.show(.error("Something went wrong"))
ToastManager.shared.show(.warning("Session expiring soon"))

Installation

In Xcode go to File → Add Package Dependencies and paste:

https://github.com/codewithswiftly/ToastKit.git

Or in Package.swift:

.package(url: "https://github.com/codewithswiftly/ToastKit.git", from: "1.0.0")

Setup

Add .toastContainer() once to your root view. That's it.

// In your App file
import SwiftUI
import ToastKit

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .toastContainer()  // ← add this once
        }
    }
}

How to Use

Option 1 — Call from anywhere (recommended)

import ToastKit

// In a ViewModel, button action, async task — anywhere
ToastManager.shared.show(.success("Saved!"))
ToastManager.shared.show(.error("Could not connect"))
ToastManager.shared.show(.warning("Low storage"))
ToastManager.shared.show(.info("New version available"))
ToastManager.shared.show(.plain("Copied to clipboard"))

Option 2 — SwiftUI binding style

struct ProfileView: View {
    @State private var toast: Toast? = nil

    var body: some View {
        Button("Save Profile") {
            toast = .success("Profile updated!")
        }
        .toast($toast)   // ← binds the state to ToastKit
    }
}

Custom toast

// Custom icon (SF Symbol), color, duration, and position
let toast = Toast(
    message: "Achievement unlocked!",
    style: .custom(icon: "star.fill", color: .purple),
    duration: 5,
    position: .bottom
)
ToastManager.shared.show(toast)

Dismiss early

// Dismiss the current toast immediately
ToastManager.shared.dismiss()

// Toasts can also be dismissed by tapping them

Toast Styles

Style Icon Color Use for
.success ✅ checkmark Green Completed actions
.error ❌ xmark Red Failures, errors
.warning ⚠️ triangle Orange Cautions
.info ℹ️ info Blue Neutral messages
.plain 🔔 bell Grey Simple status
.custom(icon:color:) Any SF Symbol Any Color Your own style

Toast Positions

// Show at the top (default)
ToastManager.shared.show(.success("Done!", position: .top))

// Show at the bottom
ToastManager.shared.show(.info("Syncing...", position: .bottom))

Queue Behaviour

If you call .show() multiple times rapidly, ToastKit queues them and shows them one at a time. You never get two toasts overlapping.

// These will show in order, one after the other
ToastManager.shared.show(.success("Step 1 complete"))
ToastManager.shared.show(.info("Step 2 starting"))
ToastManager.shared.show(.success("All done!"))

Real World Example — Settings Screen

struct SettingsView: View {

    @State private var username = ""

    var body: some View {
        Form {
            TextField("Username", text: $username)

            Button("Save Changes") {
                Task { await saveChanges() }
            }

            Button("Delete Account", role: .destructive) {
                ToastManager.shared.show(
                    Toast(
                        message: "Account deleted. Sorry to see you go.",
                        style: .error,
                        duration: 5,
                        position: .bottom
                    )
                )
            }
        }
    }

    func saveChanges() async {
        do {
            try await API.updateProfile(username: username)
            ToastManager.shared.show(.success("Username updated!"))
        } catch {
            ToastManager.shared.show(.error("Failed to save. Try again."))
        }
    }
}

Project Structure

ToastKit/
├── Sources/ToastKit/
│   ├── Toast.swift                  # The Toast model + convenience factories
│   ├── ToastManager.swift           # Observable manager — show, dismiss, queue
│   ├── ToastView.swift              # The SwiftUI view that renders a toast
│   ├── ToastContainerModifier.swift # .toastContainer() — attach to root view
│   └── ToastModifier.swift          # .toast($binding) — SwiftUI binding style
└── Tests/ToastKitTests/
    └── ToastKitTests.swift

Requirements

  • iOS 16+
  • Swift 5.9+
  • Xcode 15+
  • Zero dependencies — pure SwiftUI

License

MIT © 2026 Rahul Das Gupta


Show Your Support

If you found this project useful, consider giving it a ⭐️ on GitHub!

About

Lightweight, beautiful toast notifications for SwiftUI — no UIKit required.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages