Toast

Display ephemeral notifications that automatically dismiss. Supports multiple variants, actions, progress bars, and swipe-to-dismiss.

Import

import PrettyUI

Quick Start

There are two ways to show toasts:

1. Binding-Based (Simple)

@State private var showToast = false

Button("Show Toast") {
    showToast = true
}
.pToast(
    isPresented: $showToast,
    title: "Success!",
    variant: .success
)

2. Manager-Based (Advanced)

@StateObject private var toastManager = PToastManager()

Button("Show Toast") {
    toastManager.show("Success!", variant: .success)
}
.pToastContainer(manager: toastManager)

Variants

Four semantic variants are available:

// Info (default)
toastManager.show("Info message", variant: .info)

// Success
toastManager.show("Transaction complete!", variant: .success)

// Warning
toastManager.show("Check your connection", variant: .warning)

// Error
toastManager.show("Something went wrong", variant: .error)
VariantColorIconBest For
.infoPrimaryinfo.circle.fillNeutral information
.successGreencheckmark.circle.fillConfirmations
.warningOrangeexclamationmark.triangle.fillCautions
.errorRedxmark.circle.fillErrors

Position

Show toasts at top or bottom:

// Top (default)
.pToast(isPresented: $show, title: "Top", position: .top)

// Bottom
.pToast(isPresented: $show, title: "Bottom", position: .bottom)

// With manager
let manager = PToastManager(position: .bottom)

Duration

Control auto-dismiss timing:

// Default 3 seconds
toastManager.show("Quick message", duration: 3.0)

// Longer duration
toastManager.show("Read this carefully", duration: 5.0)

// No auto-dismiss (manual only)
toastManager.show("Tap to dismiss", duration: nil)

With Description

Add a description for more context:

toastManager.show(
    "Wallet Connected",
    description: "Your wallet is now ready to use.",
    variant: .success
)

Custom Icons

Override the default variant icon:

toastManager.show(
    "File Uploaded",
    description: "Your file is ready to share.",
    icon: "doc.fill",
    variant: .success
)

Progress Bar

Show remaining time visually:

toastManager.show(
    "Uploading...",
    duration: 5.0,
    showProgress: true
)

Action Button

Add an action button to the toast:

toastManager.show(
    "Message archived",
    variant: .info,
    duration: 5.0,
    action: (title: "Undo", handler: {
        // Handle undo
        toastManager.show("Restored!", variant: .success)
    })
)

Dismiss on Tap

By default, tapping a toast dismisses it. Disable if needed:

toastManager.show(
    "Important",
    dismissOnTap: false,
    duration: nil  // Must tap X to dismiss
)

Multiple Toasts

The manager supports showing multiple toasts:

toastManager.show("First", variant: .info)
toastManager.show("Second", variant: .success)
toastManager.show("Third", variant: .warning)

// Dismiss all
toastManager.dismissAll()

PToastContent Builder

For binding-based toasts, use PToastContent for advanced configuration:

.pToast(isPresented: $showToast, position: .top) {
    PToastContent("Transaction Complete")
        .description("Your payment was processed.")
        .icon("checkmark.circle.fill")
        .variant(.success)
        .duration(4.0)
        .showProgress(true)
        .action("View Receipt") {
            openReceipt()
        }
        .onDismiss {
            showToast = false
        }
}

Swipe to Dismiss

Toasts support swipe gestures:

  • Top position: Swipe up to dismiss
  • Bottom position: Swipe down to dismiss

Real-World Examples

Form Submission

func submitForm() {
    Task {
        do {
            try await api.submit(form)
            toastManager.show(
                "Submitted!",
                description: "We'll be in touch soon.",
                variant: .success
            )
        } catch {
            toastManager.show(
                "Submission Failed",
                description: error.localizedDescription,
                variant: .error
            )
        }
    }
}

Undo Action

func deleteItem(_ item: Item) {
    let deleted = item
    items.removeAll { $0.id == item.id }
    
    toastManager.show(
        "Item deleted",
        variant: .info,
        duration: 5.0,
        action: (title: "Undo", handler: {
            items.append(deleted)
        })
    )
}

Copy to Clipboard

func copyToClipboard(_ text: String) {
    UIPasteboard.general.string = text
    toastManager.show("Copied!", variant: .success, duration: 2.0)
}

API Reference

PToastManager

@StateObject var manager = PToastManager(position: .top)

// Show simple toast
manager.show(_ title: String, variant: PToastVariant, duration: TimeInterval?)

// Show detailed toast
manager.show(
    _ title: String,
    description: String?,
    icon: String?,
    variant: PToastVariant,
    duration: TimeInterval?,
    showProgress: Bool,
    dismissOnTap: Bool,
    action: (title: String, handler: () -> Void)?
)

// Dismiss
manager.dismiss(_ toast: PToastItem)
manager.dismiss(id: UUID)
manager.dismissAll()

View Modifiers

pToastContainer

.pToastContainer(manager: PToastManager)

pToast (Simple)

.pToast(
    isPresented: Binding<Bool>,
    title: String,
    description: String? = nil,
    icon: String? = nil,
    variant: PToastVariant = .info,
    position: PToastPosition = .top,
    duration: TimeInterval? = 3.0
)

pToast (Custom Content)

.pToast(
    isPresented: Binding<Bool>,
    position: PToastPosition = .top,
    @ViewBuilder content: () -> Content
)

PToastContent Modifiers

ModifierTypeDescription
.variant(_:)PToastVariantVisual style
.position(_:)PToastPositionTop or bottom
.duration(_:)TimeInterval?Auto-dismiss time
.showProgress(_:)BoolShow progress bar
.dismissOnTap(_:)BoolTap to dismiss
.icon(_:)StringSF Symbol name
.description(_:)String?Description text
.haptics(_:)BoolHaptic feedback
.action(_:action:)String, () -> VoidAction button
.radius(_:)RadiusSizeCorner radius
.maxWidth(_:)CGFloatMaximum width
.onDismiss(_:)() -> VoidDismiss callback

Enums

PToastVariant

  • .info — Informational (blue)
  • .success — Success (green)
  • .warning — Warning (orange)
  • .error — Error (red)

PToastPosition

  • .top — Top of screen
  • .bottom — Bottom of screen