Skip to content

Commit

Permalink
Merge pull request #2 from banghuazhao/bz/task/Add-ToastStyle
Browse files Browse the repository at this point in the history
Add ToastStyle
  • Loading branch information
banghuazhao authored Sep 19, 2024
2 parents cd914f6 + 2c79b44 commit 4ed1d77
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 99 deletions.
53 changes: 34 additions & 19 deletions EasyToastExample/EasyToastExample/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,53 @@ import SwiftUI

struct ContentView: View {
@State var showToast: Bool = false
@State var showSimpleMessageToastOnTop: Bool = false
@State var showSimpleMessageToastOnCenter: Bool = false
@State var showSimpleMessageToastOnBottom: Bool = false
@State var showCustomToast: Bool = false
@State var showDefaultToastOnTop: Bool = false
@State var showDefaultToastOnCenter: Bool = false
@State var showDefaultToastOnBottom: Bool = false
@State var showCustomToastStyle1: Bool = false
@State var showCustomToastStyle2: Bool = false
@State var showCustomToastStyle3: Bool = false
@State var showCustomToastView: Bool = false

var body: some View {
List {
Button("Simple Message Toast") {
Button("Default Toast") {
showToast = true
}
Button("Simple Message Toast on Top") {
showSimpleMessageToastOnTop = true
Button("Default Toast on Top") {
showDefaultToastOnTop = true
}
Button("Simple Message Toast on Center") {
showSimpleMessageToastOnCenter = true
Button("Default Toast on Center") {
showDefaultToastOnCenter = true
}
Button("Simple Message Toast on Bottom") {
showSimpleMessageToastOnBottom = true
Button("Default Toast on Bottom") {
showDefaultToastOnBottom = true
}
Button("Custom Message Toast") {
showCustomToast = true
Button("Custom Toast Style 1: background and text color") {
showCustomToastStyle1 = true
}
Button("Custom Toast Style 2: font, corner radius and padding") {
showCustomToastStyle2 = true
}
Button("Custom Toast Style 3: shadow and text alignment") {
showCustomToastStyle3 = true
}
Button("Custom Toast View") {
showCustomToastView = true
}
}
.easyToast(isPresented: $showToast, message: "This is a toast message")
.easyToast(isPresented: $showSimpleMessageToastOnTop, message: "Simple Message Toast on Top", position: .top)
.easyToast(isPresented: $showSimpleMessageToastOnCenter, message: "Simple Message Toast on Center", position: .center)
.easyToast(isPresented: $showSimpleMessageToastOnBottom, message: "Simple Message Toast on Bottom", position: .bottom)
.easyToast(isPresented: $showCustomToast) {
.easyToast(isPresented: $showToast, message: "Default Toast")
.easyToast(isPresented: $showDefaultToastOnTop, message: "Default Toast on Top", position: .top)
.easyToast(isPresented: $showDefaultToastOnCenter, message: "Default Toast on Center", position: .center)
.easyToast(isPresented: $showDefaultToastOnBottom, message: "Default Toast on Bottom", position: .bottom)
.easyToast(isPresented: $showCustomToastStyle1, message: "Custom Toast Style 1", style: ToastStyle(backgroundColor: .blue, textColor: .white))
.easyToast(isPresented: $showCustomToastStyle2, message: "Custom Toast Style 2", style: ToastStyle(font: .system(size: 20), cornerRadius: 20, padding: .init(top: 10, leading: 20, bottom: 10, trailing: 20)))
.easyToast(isPresented: $showCustomToastStyle3, message: "Custom Toast Style 3: shadow and text alignment and more text for test", style: ToastStyle(shadow: .gray, multilineTextAlignment: .leading))
.customToast(isPresented: $showCustomToastView) {
HStack {
Image(systemName: "checkmark.circle")
.foregroundColor(.white)
Text("Show Custom Toast Success")
Text("Show Toast Success")
.foregroundColor(.white)
}
.padding()
Expand Down
44 changes: 35 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
# EasyToast

**EasyToast** is a simple, lightweight, flexible, and easy-to-use library for showing toast in **SwiftUI**. Whether you need a quick and easy way to present a brief message to your users or a fully custom-designed toast, EasyToast provides the tools to do it seamlessly.
[![Version](https://img.shields.io/github/v/release/banghuazhao/EasyToast)](https://github.com/banghuazhao/EasyToast/releases)
[![License](https://img.shields.io/github/license/banghuazhao/EasyToast)](LICENSE)
[![Platform](https://img.shields.io/badge/platform-iOS%20|%20macOS-blue)](#)
[![Swift Package Manager](https://img.shields.io/badge/SPM-compatible-brightgreen.svg)](https://swift.org/package-manager/)

## Introduction

**EasyToast** is a lightweight and customizable SwiftUI package that provides easy-to-use toast notifications. Display brief messages to your users with minimal effort.


## Features

- **Simple Text Toasts**: Display a quick message to the user with just a few lines of code.
- **Custom Toast Views**: Create and display fully custom-designed toast notifications.
- **Flexible Positioning**: Position the toast at the top, center, or bottom of the screen.
- **Configurable Duration**: Control how long the toast remains visible.
- **Customizable appearance**: Control background color, text color, corner radius, font, padding, shadow, and text alignment
- **Interactive toasts**: Working in progress 🔨
- **Toast queueing**: Working in progress 🔨
- **Improved animations**: Working in progress 🔨
- **Internationalization**: Working in progress 🔨
- **Accessibility support**: Working in progress 🔨

## 🧳 Requirements

Expand All @@ -20,9 +34,17 @@

You can add EasyToast to your project using [Swift Package Manager](https://swift.org/package-manager/).

1. In Xcode, go to `File > Add Packages...`
2. Enter the package URL: https://github.com/banghuazhao/EasyToast
3. Select the desired version or branch and add it to your project.
1. Open your project in Xcode.
2. Go to `File > Add Packages Dependencies...`
3. Enter the package URL: https://github.com/banghuazhao/EasyToast
3. Choose the latest release

Alternatively, add the following to your `Package.swift` file:
```swift
dependencies: [
.package(url: "https://github.com/banghuazhao/EasyToast.git", from: "1.0.0")
]
```

## 🛠 Usage

Expand All @@ -33,9 +55,13 @@ To display a simple toast with a message, use the `easyToast` modifier:
```swift
import EasyToast

var body: some View {
content
.easyToast(isPresented: $showToast, message: "This is a toast message")
struct ContentView: View {
@State private var showToast = false

var body: some View {
content
.easyToast(isPresented: $showToast, message: "Hello, EasyToast!")
}
}
```

Expand All @@ -61,7 +87,7 @@ To display a custom-designed toast view, use the `easyToast` modifier with a cus
```swift
var body: some View {
content
.easyToast(isPresented: $showToast, duration: 3, position: .bottom) {
.customToast(isPresented: $showToast, duration: 3, position: .bottom) {
HStack {
Image(systemName: "checkmark.circle")
.foregroundColor(.white)
Expand All @@ -79,4 +105,4 @@ var body: some View {

## 💡 Idea

The toast is implemented by overlaying a custom view on top of the view that applies the `.easyToast` modifier, ensuring it seamlessly appears over the current content without disrupting the underlying layout
The toast is implemented by overlaying a custom view on top of the view that applies the `.easyToast` modifier, ensuring it seamlessly appears over the current content without disrupting the underlying layout
131 changes: 131 additions & 0 deletions Sources/EasyToast/CustomToast.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
//
// Created by Banghua Zhao on 19/09/2024
// Copyright Apps Bay Limited. All rights reserved.
//


import SwiftUI

struct CustomToast<CustomView: View>: ViewModifier {
@Binding var isPresented: Bool
private let duration: Double
private let position: ToastPosition
let customView: CustomView

init(
isPresented: Binding<Bool>,
position: ToastPosition,
duration: Double,
customView: CustomView
) {
_isPresented = isPresented
self.duration = duration
self.position = position
self.customView = customView
}

@State private var showToast: Bool = false

public func body(content: Content) -> some View {
content
.overlay(alignment: alignment) {
if showToast {
toast
}
}
.onChange(of: isPresented) { newValue in
if newValue == true {
withAnimation {
showToast = true
}
Task { @MainActor in
try? await Task.sleep(nanoseconds: UInt64(duration) * 1000000000)
withAnimation {
isPresented = false
showToast = false
}
}
}
}
}

@ViewBuilder
private var toast: some View {
switch position {
case .top:
toastView
.transition(.move(edge: .top).combined(with: .opacity))
case .center:
toastView
.transition(.opacity)
case .bottom:
toastView
.transition(.move(edge: .bottom).combined(with: .opacity))
}
}

@ViewBuilder
private var toastView: some View {
customView
}

private var alignment: Alignment {
switch position {
case .top:
.top
case .center:
.center
case .bottom:
.bottom
}
}
}

public extension View {
/**
Displays a toast notification with a custom view.
- Parameters:
- isPresented: A binding to a boolean value that determines whether the toast is presented.
- duration: The duration in seconds for which the toast is displayed. The default value is 2 seconds.
- position: The position on the screen where the toast is displayed. The default is `.center`.
- customView: A closure that returns the custom view to be displayed as the toast content.
- Returns: A view that displays the original content overlaid with a custom toast view when `isPresented` is `true`.
Use this method to present a custom-designed toast view. The toast will automatically disappear after the specified duration.
- Note: The toast will only appear when `isPresented` is set to `true`.
Example usage:
```swift
Text("Hello, World!")
.customToast(isPresented: $showToast, duration: 3, position: .bottom) {
HStack {
Image(systemName: "checkmark.circle")
.foregroundColor(.white)
Text("Show Custom Toast Success")
.foregroundColor(.white)
}
.padding()
.background(Color.green)
.cornerRadius(20)
}
```
*/
func customToast(
isPresented: Binding<Bool>,
duration: Double = 2,
position: ToastPosition = .center,
@ViewBuilder customView: @escaping () -> some View
) -> some View {
modifier(
CustomToast(
isPresented: isPresented,
position: position,
duration: duration,
customView: customView()
)
)
}
}
Loading

0 comments on commit 4ed1d77

Please sign in to comment.