Skip to content

wlsdms0122/JSToast

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JSToast

JSToast is fully customizable toast package.

Requirements

  • iOS 14.0+

Installation

Swift Pacakge Manager

dependencies: [
    .package(url: "https://github.com/wlsdms0122/JSToast.git", from: "2.0.0")
]

Getting Started

To display a toast, you first need to create a view. This view is created using the Toast initializer and will be used to display the toast message.

let toastView = UILabel()
toastView.backgroundColor = .black.withAlphaComponent(0.6)
toastView.text = "Hello World!"
toastView.textColor = .white
                
let toast = Toast(toastView)

⚠️ It is recommended that the toast view has its own size.

Once you have defined a toast, you can display or hide it on the screen using the show function.

toast.show(
    withDuration: 3,
    layouts: [
        .center(of: .x),
        .inside(of: .bottom, of: button, offset: 16)
    ]
)

The show function has many optional parameters, but most of them have default values. This makes it easy to display a toast message with just a few lines of code.

Layout

JSToast offers multiple layout types for positioning your toast messages. These layouts include options to position the toast inside or outside a target view, or to center it along a specific axis.

Below are the available layout methods.

extension Layout {
    /// Positions the toast inside the specified anchor of the target view.
    static func inside(_ anchor: Anchor, of target: UIView? = nil, offset: CGFloat = 0, ignoresSafeArea: Bool = false) -> Self
    /// Positions the toast outside the specified anchor of the target view.
    static func outside(_ anchor: Anchor, of target: UIView? = nil, offset: CGFloat = 0) -> Self
    /// Centers the toast along the specified axis of the target view.
    static func center(_ axis: Axis, of target: UIView? = nil, offset: CGFloat = 0, ignoresSafeArea: Bool = false) -> Self
    /// Sets a fixed width for the toast.
    static func width(_ width: CGFloat) -> Self
    /// Sets a fixed height for the toast.
    static func height(_ height: CGFloat) -> Self
}

When specifying a layout, the target parameter determines the view relative to which the toast will be positioned. If the target parameter is not specified (i.e., set to nil), the toast will reference its layer for positioning. If the layer is also nil, the toast will default to referencing the window for its positioning.

By using inside or outside layouts with the target parameter, you can position the toast relative to a specific view.

toast.show(
    withDuration: 3,
    layouts: [
        .center(of: .x),
        .outside(of: .top, of: button, offset: 16)
    ]
)

Animation

JSToast allows you to set default animations or create custom animations for controlling how the toast appears and disappears from the screen. The showAnimation and hideAnimation parameters of the show function are used to define these animations.

extension ToastAnimation {
    static func fadeIn(duration: TimeInterval, curve: UIView.AnimationCurve = .easeInOut) -> Self
    static func fadeOut(duration: TimeInterval, curve: UIView.AnimationCurve = .easeInOut) -> Self
    static func slideIn(duration: TimeInterval, direction: Direction, curve: UIView.AnimationCurve = .easeInOut, offset: CGFloat? = nil) -> Self
    static func slideOut(duration: TimeInterval, direction: Direction, curve: UIView.AnimationCurve = .easeInOut, offset: CGFloat? = nil) -> Self
}

You can easily apply animations to your toast messages.

Below is an example where a toast slides in from left and out to the right.

toast.show(
    withDuration: 3,
    layouts: [
        .center(.x),
        .outside(.bottom, of: button, offset: 16)
    ],
    showAnimation: .slideIn(duration: 0.3, direction: .right),
    hideAnimation: .slideOut(duration: 0.3, direction: .right)
)

Custom Animation

If you want to create a custom animation, you can implement the ToastAnimation protocol. This requires the implementation of two functions.

protocol ToastAnimation {
    func play(_ view: UIView, completion: @escaping (Bool) -> Void)
    func cancel(completion: @escaping () -> Void)
}

To create custom animations, reference the default animations for guidance.

Advanced Usage

While the Toast class can be used on its own, creating a custom manager like Toaster can be more beneficial for performing complex tasks or limiting operations within your application.

Toaster is a custom class that manages Toast instances to ensure that only one toast is visible at a time. This enhances the user experience by preventing multiple toasts from being displayed simultaneously.

By implementing a custom manager like Toaster, developers can control the behavior of toasts within their application, allowing for the creation of custom workflows that best suit their project's requirements.

SwiftUI Support

JSToast supports SwiftUI through the ToastReader component. While the interface provided is similar to the UIKit version, it is implemented in a way that is more suitable for SwiftUI.

struct SampleView: View {
    var body: some View {
        ToastReader { toaster in
            Button("Show Toast") {
                isShow = true
            }
                .toastTarget("button")
                .onChange(of: isShow) { isShow in
                    if isShow {
                        toaster.show(
                            withDuration: 3,
                            layouts: [
                                .center(.x),
                                .outside(.bottom, offset: 16)
                            ],
                            target: "button"
                        ) {
                            Text("Hello World")
                                .foregroundStyle(.white)
                                .background(.black.opacity(0.6))
                        }
                    } else {
                        toaster.hide()
                    }
                }
        }
    }

    @State
    var isShow: Bool = false
}

If you want the toast to be part of a specific view hierarchy rather than appearing at the top level (window), you can use ToastLayer. This allows you to manage the positioning of the toast within a particular part of your view hierarchy.

struct SampleView: View {
    var body: some View {
        ToastReader { toaster in
            ToastLayer("toastLayer") {
                Button("Show Toast") {
                    isShow = true
                }
                    .toastTarget("button")
            }
                .onChange(of: isShow) { isShow in
                    if isShow {
                        toaster.show(
                            withDuration: 3,
                            layouts: [
                                .center(.x),
                                .outside(.bottom, offset: 16)
                            ],
                            target: "button",
                            layer: "toastLayer"
                        ) {
                            Text("Hello World")
                                .foregroundStyle(.white)
                                .background(.black.opacity(0.6))
                        }
                    } else {
                        toaster.hide()
                    }
                }
        }
    }

    @State
    var isShow: Bool = false
}

You can also easily display a .toast() using the toast view modifier. For more details, check out the code examples.

Contribution

Any ideas, issues, opinions are welcome.

License

JSToast is available under the MIT license.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages