|
//
// Toast.swift
// PaiaiDataKit
//
// Created by FFIB on 2019/1/21.
// Copyright © 2019 FFIB. All rights reserved.
//
import UIKit
private let globalInstance = Toast()
public class Toast {
public enum ToastType {
case text(String)
case image(UIImage?)
case imageWithText(UIImage?, String)
case activityIndicator(String?)
}
public enum PresentationStyle {
case center
case custom(animator: ToastAnimator)
var animator: ToastAnimator {
switch self {
case .center:
return FadeToastAnimator()
case let .custom(animator):
return animator
}
}
}
public enum AnimationDuration {
case none
case duration(TimeInterval)
}
public struct Config {
public init() {}
public var toastType: ToastType = .text("")
public var presentationStyle: PresentationStyle = .center
public var duration: AnimationDuration = .duration(1)
public var option: ToastOption = .default
public static var `default`: Config {
return Config()
}
}
private var _toastView: ToastView?
private var _config: Config = .default
private var _task: DispatchWorkItem?
}
/// MARK: - APIS
public extension Toast {
func show(config: Config = .default, in view: UIView? = UIApplication.shared.keyWindow) {
self._config = config
if _toastView == nil {
let toastView = ToastView(option: config.option, type: config.toastType)
view?.addSubview(toastView)
_toastView = toastView
showAnimation()
} else {
if case let .duration(interval) = config.duration {
if let task = _task {
_ = task.wait(timeout: .now() + interval)
} else {
self._task = DispatchWorkItem(block: {
self.hideAnimation()
})
DispatchQueue.main.asyncAfter(deadline: .now() + interval, execute: self._task!)
}
} else {
_task?.cancel()
_task = nil
}
_toastView?.option = config.option
_toastView?.toastType = config.toastType
_toastView?.switchToast()
}
}
func show(message: String, in view: UIView? = UIApplication.shared.keyWindow) {
var config = Config()
config.toastType = .text(message)
show(config: config, in: view)
}
func show(image: UIImage?, in view: UIView? = UIApplication.shared.keyWindow) {
var config = Config()
config.toastType = .image(image)
show(config: config, in: view)
}
func show(message: String, image: UIImage?, in view: UIView? = UIApplication.shared.keyWindow) {
var config = Config()
config.toastType = .imageWithText(image, message)
show(config: config, in: view)
}
func showActivity(message: String?, in view: UIView? = UIApplication.shared.keyWindow) {
var config = Config()
config.toastType = .activityIndicator(message)
config.duration = .none
show(config: config, in: view)
}
func hide() {
hideAnimation()
}
private func showAnimation() {
guard let toastView = _toastView else { return }
_config.presentationStyle.animator.toastIn(in: toastView) {[weak self] _ in
guard let `self` = self else { return }
switch self._config.duration {
case .none:
break
case let .duration(interval):
self._task = DispatchWorkItem(block: {
self.hideAnimation()
})
DispatchQueue.main.asyncAfter(deadline: .now() + interval, execute: self._task!)
}
}
}
private func hideAnimation() {
guard let toastView = _toastView else { return }
_config.presentationStyle.animator.toastOut(in: toastView) {[weak self] (_) in
guard let `self` = self else { return }
self.clear()
}
}
private func clear() {
_toastView?.removeFromSuperview()
_toastView = nil
_task = nil
}
}
/// MARK: - Static APIS
public extension Toast {
static var share: Toast {
return globalInstance
}
static func show(config: Config = .default, in view: UIView? = UIApplication.shared.keyWindow) {
globalInstance.show(config: config, in: view)
}
static func show(message: String, in view: UIView? = UIApplication.shared.keyWindow) {
globalInstance.show(message: message, in: view)
}
static func show(image: UIImage?, in view: UIView? = UIApplication.shared.keyWindow) {
globalInstance.show(image: image, in: view)
}
static func show(message: String, image: UIImage?, in view: UIView? = UIApplication.shared.keyWindow) {
globalInstance.show(message: message, image: image, in: view)
}
static func showActivity(message: String?, in view: UIView? = UIApplication.shared.keyWindow) {
globalInstance.showActivity(message: message, in: view)
}
static func hide() {
globalInstance.hide()
}
}
|