class SnackBar: UIWindow {
private let view = UIView()
private let label = UILabel()
private let aniDuration: TimeInterval = 0.3
private let showDuration: TimeInterval = 2
convenience init() {
self.init(frame: UIScreen.main.bounds)
}
convenience init(bottom offset: CGFloat = 0) {
self.init(frame: UIScreen.main.bounds)
constraints.first(where: {$0.firstAttribute == .bottom})?.constant = -(16 + offset)
}
override init(frame: CGRect) {
super.init(frame: frame)
initView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initView()
}
private func initView() {
tag = "SnackBar".hashValue
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(instantRemove)))
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.cornerRadius = 10
view.backgroundColor = "2BC3BA".color
addSubview(view)
NSLayoutConstraint.activate([
view.heightAnchor.constraint(greaterThanOrEqualToConstant: 38),
view.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor, constant: 16),
view.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor, constant: -16),
view.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -16)
])
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 12)
label.textColor = .white
label.numberOfLines = 2
view.addSubview(label)
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
label.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
label.topAnchor.constraint(equalTo: view.topAnchor, constant: 8),
label.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8)
])
}
func show(_ text: String) {
guard let snackBar = UIApplication.shared.windows.first(where: {$0 is SnackBar}), snackBar.isHidden else {return}
alpha = 0
isHidden = false
label.text = text
UIView.animate(withDuration: aniDuration, delay: 0, options: [.allowUserInteraction], animations: {
self.alpha = 1
})
DispatchQueue.main.asyncAfter(deadline: .now() + aniDuration + showDuration) {
guard self.alpha == 1 else {return}
UIView.animate(withDuration: self.aniDuration, delay: 0, options: [.allowUserInteraction], animations: {
self.alpha = 0
}, completion: { _ in
self.isHidden = true
})
}
}
@objc func instantRemove() {
UIView.animate(withDuration: aniDuration, delay: 0, options: [.allowUserInteraction], animations: {
self.alpha = 0
}, completion: { _ in
self.isHidden = true
})
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return view.frame.contains(point)
}
}