70 lines
2.1 KiB
Swift
70 lines
2.1 KiB
Swift
import UIKit
|
|
|
|
struct NotificationBanner {
|
|
enum Style {
|
|
case fail, ok
|
|
}
|
|
|
|
let view: UIView
|
|
|
|
init(_ msg: String, style: Style) {
|
|
let bg, fg: UIColor
|
|
let imgName: String
|
|
switch style {
|
|
case .fail:
|
|
bg = .systemRed
|
|
fg = UIColor.black.withAlphaComponent(0.80)
|
|
imgName = "circle-x"
|
|
case .ok:
|
|
bg = .systemGreen
|
|
fg = UIColor.black.withAlphaComponent(0.65)
|
|
imgName = "circle-check"
|
|
}
|
|
view = UIView()
|
|
view.backgroundColor = bg
|
|
let lbl = QuickUI.label(msg, style: .callout)
|
|
lbl.textColor = fg
|
|
lbl.numberOfLines = 0
|
|
lbl.font = lbl.font.bold()
|
|
let img = QuickUI.image(UIImage(named: imgName))
|
|
img.tintColor = fg
|
|
view.addSubview(lbl)
|
|
view.addSubview(img)
|
|
img.anchor([.centerY], to: view.layoutMarginsGuide)
|
|
lbl.anchor([.top, .bottom, .trailing], to: view.layoutMarginsGuide)
|
|
img.widthAnchor =&= 25
|
|
img.heightAnchor =&= 25
|
|
if #available(iOS 11, *) {
|
|
img.leadingAnchor =&= view.layoutMarginsGuide.leadingAnchor
|
|
} else {
|
|
img.leadingAnchor =&= view.leadingAnchor + 8
|
|
}
|
|
lbl.leadingAnchor =&= img.trailingAnchor + 8
|
|
img.bottomAnchor =<= view.bottomAnchor - 8 | .init(rawValue: 999)
|
|
lbl.bottomAnchor =<= view.bottomAnchor - 8 | .init(rawValue: 999)
|
|
}
|
|
|
|
/// Animate header banner from the top of the view. Show for `delay` seconds and then hide again.
|
|
/// - Parameter onClose: Run after the close animation finishes.
|
|
func present(in vc: UIViewController, hideAfter delay: TimeInterval = 3, onClose: (() -> Void)? = nil) {
|
|
vc.view.addSubview(view)
|
|
view.anchor([.leading, .trailing], to: vc.view!)
|
|
view.widthAnchor =&= vc.view!.widthAnchor // Bug? left-right is not sufficient
|
|
vc.view.layoutIfNeeded() // sets the height
|
|
let h = view.frame.height
|
|
let constraint = view.topAnchor =&= vc.view.topAnchor - h
|
|
vc.view.layoutIfNeeded() // hide view
|
|
UIView.animate(withDuration: 0.3, animations: {
|
|
constraint.constant = 0
|
|
vc.view.layoutIfNeeded() // animate view
|
|
UIView.animate(withDuration: 0.3, delay: delay, options: .curveLinear, animations: {
|
|
constraint.constant = -h
|
|
vc.view.layoutIfNeeded() // hide again
|
|
}, completion: { _ in
|
|
self.view.removeFromSuperview()
|
|
onClose?()
|
|
})
|
|
})
|
|
}
|
|
}
|