Skip to content

Commit

Permalink
Update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsaidi committed Apr 24, 2024
1 parent 06a2f32 commit 61fed4e
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 139 deletions.
60 changes: 53 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The result can look like this, or completely different:
<img src="Resources/Demo.gif" width=350 />
</p>

These notifications can be styled and customized to great extent. You can also use completely custom views.
System notifications can be styled and customized. You can use a native-looking `SystemNotificationMessage` view as the content view, or any custom view.



Expand All @@ -39,23 +39,69 @@ https://github.com/danielsaidi/SystemNotification.git

## Getting started

After adding SystemNotification to your project, you can add a system notification to a view hierarchy just as you add a `sheet`, `alert` and `fullScreenModal`:
With SystemNotification, you can add a system notification to any view just as you add a `sheet`, `alert` and `fullScreenModal`, by applying a `systemNotification` view modifier (preferably to the application root view).

State-based notifications take a boolean state binding and a view builder:

```swift
import SystemNotification

struct MyView: View {

@State
var isActive = false

var body: some View {
VStack {
Button("Show notification") {
isActive = true
}
}
.systemNotification(isActive: $isActive) {
Text("You can use any custom content view")
.padding()
}
}
}
```

Context-based notifications just take a `SystemNotificationContext` instance and can then show many different notifications with a single modifier:

```swift
import SystemNotification

struct MyView: View {

@StateObject
var notification = SystemNotificationContext()

var body: some View {
Text("Hello, world")
.systemNotification(...)
VStack {
Button("Show text") {
notification.present {
Text("Context-based notifications are more flexible.")
.padding()
.multilineTextAlignment(.center)
}
}
Button("Show message") {
notification.present {
SystemNotificationMessage(
icon: Text("👍"),
title: "Great job!",
text: "You presented a native-looking message!"
)
}
}
}
.systemNotification(notification)
}
}
```

You can use both state- and context and message-based notifications and style your notifications to great extent.
The `SystemNotificationMessage` view lets you easily mimic a native notification view, with an icon, title and text, but you can use any custom view as the notification body.

For more information, please see the [getting started guide][Getting-Started].
For more information about how to configure and style your notifications, please see the [getting started guide][Getting-Started].



Expand All @@ -67,7 +113,7 @@ The [online documentation][Documentation] has more information, articles, code e

## Demo Application

The demo app lets you explore the library with iOS, macOS, and visionOS. To try it out, just open and run the `Demo` project.
The demo app lets you explore the library. To try it out, just open and run the `Demo` project.



Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Demo App

This article describes how to try the SystemNotification demo app.
This article describes the SystemNotification demo app.

@Metadata {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,165 +17,73 @@ This article describes how to get started with SystemNotification.

## Overview

After adding SystemNotification to your project, you can add a system notification to a view just as you add a sheet, alert or full screen modal, using ``SwiftUI/View/systemNotification(_:)`` or ``SwiftUI/View/systemNotification(isActive:content:)``:

```swift
import SystemNotification

struct MyView: View {

var body: some View {
Text("Hello, world")
.systemNotification(...)
}
}
```

You can use both state and ``SystemNotificationContext``-based notifications and style your custom notifications to great extent.

> Important: If you want a system notification to be global, make sure to apply the notification modifier to the application root view, e.g. the main `TabView` or `NavigationStack`. You must apply the modifier again if you present a sheet or full screen modal.
After adding SystemNotification to your project, you can add a system notification to any view just as you add a `sheet`, `alert` and `fullScreenModal`, with a simple view modifier.

To add a system notification to a view, just use the ``SwiftUI/View/systemNotification(_:)`` view modifier with a state binding or a ``SystemNotificationContext`` instance.

> Important: Since system notifications should be as global as possible, make sure to apply the view modifier to the application root view, e.g. the main `NavigationStack` or ``TabView``. Any new sheets or modals must also have the modifier applied.
## State-based notifications

State-based notifications work like state-based `sheet`, `alert` and `fullScreenModal` modifiers, and take an `isActive` binding:
State-based notifications take a boolean state binding and a view builder:

```swift
struct ContentView: View {
import SystemNotification

struct MyView: View {

@State
private var isActive = false
@State
var isActive = false

var body: some View {
NavigationView {
List {
Button("Show") { isActive = true }
Button("Hide") { isActive = false }
Button("Toggle") { isActive.toggle() }
VStack {
Button("Show notification") {
isActive = true
}
}
.systemNotification(isActive: $isActive) {
SystemNotificationMessage(
icon: Image(systemName: "star.fill")
text: Text("This is a standard notification message with just the small text and a star icon")
)
Text("You can use any custom content view")
.padding()
}
}
}
```

State-based notifications are easy to use, but less flexible than context-based ones, since they are meant to present a specific view.



## Context-based notifications

Context-based notifications use an observable ``SystemNotificationContext`` instead of state:
Context-based notifications just take a ``SystemNotificationContext`` instance and can then show many different notifications with a single modifier:

```swift
struct ContentView: View {

@StateObject
private var notification = SystemNotificationContext()

var body: some View {
NavigationView {
List {
Button("Show notification", action: showNotification)
Button("Show orange notification", action: showCustomNotification)
}
}
.environmentObject(notification)
.systemNotification(notification)
}

func showNotification() {
notification.present {
SystemNotificationMessage(
icon: Image(systemName: "􀋚"),
title: Text("Silent mode")
text: Text("Off"),
style: .init(iconColor: .red)
)
}
}

func showCustomNotification() {
notification.present(
configuration: .init(backgroundColor: .orange)
) {
VStack {
Text("Custom notification")
.font(.headline)
Divider()
Text("SystemNotification supports using any content views you like.")
}
.foregroundColor(.white)
.padding()
}
}
}
```

In the code above, we apply a notification context to the view, and also pass it as an environment object to let other views use it as well.



## Notification views

You can present any custom view as a system notification, for instance plain text:
import SystemNotification

```swift
struct MyView: View {

@StateObject
private var notification = SystemNotificationContext()
@StateObject
var notification = SystemNotificationContext()

var body: some View {
List {
Button("Show notification", action: showNotification)
VStack {
Button("Show text") {
notification.present {
Text("Context-based notifications are more flexible.")
.padding()
.multilineTextAlignment(.center)
}
}
Button("Show message") {
notification.present {
SystemNotificationMessage(
icon: Text("👍"),
title: "Great job!",
text: "You presented a native-looking message!"
)
}
}
}
.systemNotification(notification)
}

func showNotification() {
notification.present {
Text("Hello, world!")
}
}
}
```

You can use a ``SystemNotificationMessage`` to easily mimic a iOS system notification:

```swift
struct MyView: View {

@StateObject
private var notification = SystemNotificationContext()
The ``SystemNotificationMessage`` view lets you easily mimic a native notification view, with an icon, an optional title and a text, but you can use any custom view as the notification content view.

var body: some View {
List {
Button("Show notification", action: showNotification)
}
.systemNotification(notification)
}

func showNotification() {
notification.present {
SystemNotificationMessage(
icon: Image(systemName: "bell.slash.fill"),
title: "Silent Mode",
text: "On"
)
.systemNotificationMessageStyle(
.init(iconColor: .red)
)
}
}
}
```
You can use the ``SwiftUI/View/systemNotificationConfiguration(_:)`` and ``SwiftUI/View/systemNotificationStyle(_:)`` view modifiers to apply custom configurations and styles, and the ``SwiftUI/View/systemNotificationMessageStyle(_:)`` to style the message.


## Styling and configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ SystemNotification is a SwiftUI SDK that lets you mimic the native iOS system no

![SystemNotification logo](Logo.png)

SystemNotification is a SwiftUI SDK that lets you mimic the native iOS system notification that are presented when you toggle silent mode, connect your AirPods, etc.
SystemNotification is a SwiftUI SDK that lets you mimic the native iOS system notification that are presented when you toggle silent mode, connect your AirPods, etc.

These notifications can be styled and customized to great extent. You can also use completely custom views.
System notifications can be styled and customized. You can use a native-looking ``SystemNotificationMessage`` view as the content view, or any custom view.



Expand Down
58 changes: 58 additions & 0 deletions Sources/SystemNotification/SystemNotification.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public struct SystemNotification<Content: View>: View {
content(isActive)
.background(style.backgroundColor)
.background(style.backgroundMaterial)
.compositingGroup()
.cornerRadius(style.cornerRadius ?? 1_000)
.shadow(
color: style.shadowColor,
Expand Down Expand Up @@ -215,3 +216,60 @@ private extension SystemNotification {

return Preview()
}

#Preview("README #1") {

struct MyView: View {

@State
var isActive = false

var body: some View {
VStack {
Button("Show notification") {
isActive = true
}
}
.systemNotification(isActive: $isActive) {
Text("You can use any custom content view")
.padding()
}
}
}

return MyView()
}


#Preview("README #2") {

struct MyView: View {

@StateObject
var notification = SystemNotificationContext()

var body: some View {
VStack {
Button("Show text") {
notification.present {
Text("Context-based notifications are more flexible.")
.padding()
.multilineTextAlignment(.center)
}
}
Button("Show message") {
notification.present {
SystemNotificationMessage(
icon: Text("👍"),
title: "Great job!",
text: "You presented a native-looking message!"
)
}
}
}
.systemNotification(notification)
}
}

return MyView()
}

0 comments on commit 61fed4e

Please sign in to comment.