From 1b019d901e07763995613cbc1154c7e8ae4f6d83 Mon Sep 17 00:00:00 2001 From: sanzaru Date: Thu, 26 Sep 2024 20:43:58 +0200 Subject: [PATCH 1/4] Add NotificationCenter publisher --- .../SimpleToastNotificationPublisher.swift | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Sources/SimpleToast/SimpleToastNotificationPublisher.swift diff --git a/Sources/SimpleToast/SimpleToastNotificationPublisher.swift b/Sources/SimpleToast/SimpleToastNotificationPublisher.swift new file mode 100644 index 0000000..f0e8d60 --- /dev/null +++ b/Sources/SimpleToast/SimpleToastNotificationPublisher.swift @@ -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(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(perform action: @escaping (ToastNotification?) -> Void) -> some View { + onReceive(NotificationCenter.default.publisher(for: .toastNotification)) { + action($0.object as? ToastNotification) + } + } +} From 6a3b9c2c45866a55c50e52a434fe6fc420670839 Mon Sep 17 00:00:00 2001 From: sanzaru Date: Thu, 3 Oct 2024 15:41:20 +0200 Subject: [PATCH 2/4] Updated documentation --- Documentation/Usage.md | 96 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 6 deletions(-) diff --git a/Documentation/Usage.md b/Documentation/Usage.md index 396715f..688c23e 100644 --- a/Documentation/Usage.md +++ b/Documentation/Usage.md @@ -1,12 +1,22 @@ # 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 different ways to attach a toast notification to your views. The basic 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. > [!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. +> +> ⚠️ 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-edgesignoringsafeareaedges--ignoressafeareaedges) + + +## Attach via boolean You can attach the toast to a view and show it via binding to a boolean: ```swift @@ -37,8 +47,10 @@ 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. @@ -83,7 +95,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 @@ -122,7 +134,79 @@ 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 ExternalSecondView: 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: From d32cf1788b47a8f930f1b7a8344a3a52e38a7a62 Mon Sep 17 00:00:00 2001 From: sanzaru Date: Sun, 13 Oct 2024 22:58:02 +0200 Subject: [PATCH 3/4] Updated readme --- Documentation/Usage.md | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/Documentation/Usage.md b/Documentation/Usage.md index 688c23e..e3ce3d9 100644 --- a/Documentation/Usage.md +++ b/Documentation/Usage.md @@ -1,9 +1,11 @@ # SimpleToast Usage -There are different ways to attach a toast notification to your views. The basic 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 different ways to attach a toast notification to your views. The basic 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. > [!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. +> 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. @@ -13,7 +15,7 @@ There are different ways to attach a toast notification to your views. The basic - [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-edgesignoringsafeareaedges--ignoressafeareaedges) + - [Usage with `edgesIgnoringSafeArea(_:edges:)` / `ignoresSafeArea(_:edges:)`](#usage-with-edgesignoringsafearea_edges--ignoressafearea_edges) ## Attach via boolean @@ -52,7 +54,8 @@ struct ToastTestView: View { ## 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. @@ -136,11 +139,14 @@ struct ToastTestView: View { ## 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. +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. +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. +Here’s a simple example of a toast notification with a text element: ```swift import Foundation @@ -150,7 +156,8 @@ struct ToastNotification: Identifiable { 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. +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 @@ -184,7 +191,7 @@ The following demonstrates a simple view triggering the toast notification. import SwiftUI import SimpleToast -struct ExternalSecondView: View { +struct ExampleSecondView: View { var body: some View { VStack { Text("External Second View") @@ -204,11 +211,13 @@ struct ExternalSecondView: View { ``` > [!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. +> 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:) +## 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 { From ab6528208b7ff7c93a318c121b30052504b5f364 Mon Sep 17 00:00:00 2001 From: sanzaru Date: Sat, 19 Oct 2024 19:29:22 +0200 Subject: [PATCH 4/4] Updated usage documentation --- Documentation/Usage.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/Usage.md b/Documentation/Usage.md index e3ce3d9..bc00959 100644 --- a/Documentation/Usage.md +++ b/Documentation/Usage.md @@ -1,7 +1,7 @@ # SimpleToast Usage -There are different ways to attach a toast notification to your views. The basic 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