Skip to content

Commit

Permalink
Merge pull request #41 from sanzaru/notification-center-publisher
Browse files Browse the repository at this point in the history
Notification center publisher
  • Loading branch information
sanzaru authored Oct 19, 2024
2 parents 71e8c2f + ab65282 commit 7c08591
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 9 deletions.
111 changes: 102 additions & 9 deletions Documentation/Usage.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
# SimpleToast Usage

There are different ways to attach a toast notification to your views. The usage is similar to well-known SwiftUI view modifiers (e.g., alert or sheet). If you are familiar with these, using SimpleToast will be very straightforward.
There are various ways to attach a toast notification to your views. The basic usage is similar to popular SwiftUI view
modifiers, such as alert or sheet. If you’re familiar with those, using SimpleToast will be straightforward.

> [!NOTE]
> The toast always appears at the edges of the view it is attached to. Ensure the view has enough space to render the toast properly. Preferably, the toast should be attached to the outermost view or the navigation view, if available.
> Sheets need their own notification handler as they overlap all content.
> The toast always appears at the edges of the view it is attached to. Ensure the view has enough space to render the
> toast properly. Preferably, the toast should be attached to the outermost view or the navigation view, if available.
>
> ⚠️ Sheets need their own notification handler as they overlap all content.
### Attach via boolean
**In this article**
- [SimpleToast Usage](#simpletoast-usage)
- [Attach via boolean](#attach-via-boolean)
- [Attach via optional object](#attach-via-optional-object)
- [Run code after dismissal](#run-code-after-dismissal)
- [Using the SimpleToastNotificationPublisher](#using-the-simpletoastnotificationpublisher)
- [Usage with `edgesIgnoringSafeArea(_:edges:)` / `ignoresSafeArea(_:edges:)`](#usage-with-edgesignoringsafearea_edges--ignoressafearea_edges)


## Attach via boolean
You can attach the toast to a view and show it via binding to a boolean:

```swift
Expand Down Expand Up @@ -37,10 +49,13 @@ struct ToastTestView: View {
}
}
```
> [!TIP]
> This functionality is similar to the one of the SwiftUI [sheet(isPresented:onDismiss:content:)](https://developer.apple.com/documentation/swiftui/view/sheet(ispresented:ondismiss:content:))
### Attach via optional object
## Attach via optional object

You can trigger the toast via an instance to an optional object, which conforms to the protocol Identifiable. If the value is not nil the toast will be shown.
You can trigger the toast via an instance to an optional object, which conforms to the protocol Identifiable. If the
value is not nil the toast will be shown.

The following example is based on the previous one and also shows the toast, but this time based on a value on an item.

Expand Down Expand Up @@ -83,7 +98,7 @@ struct ToastTestView: View {
> [!TIP]
> This functionality is similar to the one of the SwiftUI [sheet(item:onDismiss:content:)](https://developer.apple.com/documentation/swiftui/view/sheet(item:ondismiss:content:))
### Run code after dismissal
## Run code after dismissal

To run custom code after the toast disappeared you just have to pass a function to the `onDismiss` parameter:
```swift
Expand Down Expand Up @@ -122,9 +137,87 @@ struct ToastTestView: View {
}
```

### Usage with edgesIgnoringSafeArea(_:edges:) / ignoresSafeArea(_:edges:)
## Using the SimpleToastNotificationPublisher

The `SimpleToastNotificationPublisher` provides a convenient way to trigger toast notifications throughout your app.
A typical example would be using the `NavigationSplitView`, where you can trigger notifications inside the sidebar view
and display them in the details view.

To use the `SimpleToastNotificationPublisher` for your toast notifications, you first need to create a data structure
that conforms to the `Identifiable` protocol.

Here’s a simple example of a toast notification with a text element:

```swift
import Foundation

struct ToastNotification: Identifiable {
let id = UUID()
let text: String
}
```
The following example demonstrates a simple example view for showing the notification. This view is not responsible for
triggering the notification. This is done by the view below this example.

```swift
import SwiftUI
import SimpleToast

struct ToastTestView: View {
@State private var notification: ToastNotification?

VStack(spacing: 20) {
Text("Some view content")
}
.onToastNotification {
notification = $0
}
.simpleToast(item: $notification, options: optionsSkew) {
HStack {
Image(systemName: "exclamationmark.triangle")
Text(notification?.message ?? "Default message")
}
.padding()
.background(Color.red.opacity(0.8))
.foregroundColor(Color.white)
.cornerRadius(10)
}
}
```

The following demonstrates a simple view triggering the toast notification.

```swift
import SwiftUI
import SimpleToast

struct ExampleSecondView: View {
var body: some View {
VStack {
Text("External Second View")

TestButton("Trigger Toast (Publisher)", identifier: "ButtonPublisher") {
withAnimation {
SimpleToastNotificationPublisher.publish(
notification: ToastNotification(text: "Toast from publisher")
)
}
}
}
.padding()
.background(Color.orange.opacity(0.3))
}
}
```

> [!IMPORTANT]
> Ensure that the view displaying the toast notification is visible. If you use sheets or other full-screen content,
> you'll need to handle the notification separately within them, as they will overlay all other views.
## Usage with `edgesIgnoringSafeArea(_:edges:)` / `ignoresSafeArea(_:edges:)`

If the view you're attaching the toast to is ignoring a safe area, make sure to apply the SimpleToast modifier **after** the modifier for ignoring the safe area:
If the view you're attaching the toast to is ignoring a safe area, make sure to apply the SimpleToast modifier **after**
the modifier for ignoring the safe area:

```swift
VStack {
Expand Down
32 changes: 32 additions & 0 deletions Sources/SimpleToast/SimpleToastNotificationPublisher.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// SimpleToastNotificationPublisher.swift
// SimpleToast
//
// This file is part of the SimpleToast Swift library: https://github.com/sanzaru/SimpleToast
// Created by Martin Albrecht on 25.09.24.
// Licensed under Apache License v2.0
//

import SwiftUI

public struct SimpleToastNotificationPublisher {
public static func publish<ToastNotification: Identifiable>(notification: ToastNotification) {
NotificationCenter.default.post(name: .toastNotification, object: notification)
}
}

private extension Notification.Name {
/// Name for published `NotificationCenter.Publisher` notifications
static let toastNotification = Notification.Name("SimpleToastNotification")
}

public extension View {
/// Handle NotificationCenter events for SimpleToast
/// - Parameter action: The action to perform when a notification is received
/// - Returns: The view the function is attached to
func onToastNotification<ToastNotification: Identifiable>(perform action: @escaping (ToastNotification?) -> Void) -> some View {
onReceive(NotificationCenter.default.publisher(for: .toastNotification)) {
action($0.object as? ToastNotification)
}
}
}

0 comments on commit 7c08591

Please sign in to comment.