[ios] refactor the Toast class class to support the inharitance

Now Toast is a facade to hide the subclass implementations from the callers.

Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
This commit is contained in:
Kiryl Kaveryn 2024-05-23 19:45:40 +04:00
parent 663dddecfa
commit 2fd0a82c1f

View file

@ -1,62 +1,51 @@
@objc(MWMToast)
final class Toast: NSObject {
class Toast: NSObject {
@objc(MWMToastAlignment)
enum Alignment: Int {
case bottom
case top
}
private var blurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
private var timer: Timer?
private static let duration: TimeInterval = 3.0
private static var toasts: [Toast] = []
@objc static func toast(withText text: String) -> Toast {
let toast = Toast(text)
toasts.append(toast)
return toast
private let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
private var timer: Timer?
var contentView: UIView { blurView.contentView }
override init() {
super.init()
setupBlurView()
Self.toasts.append(self)
}
@objc static func hideAll() {
toasts.forEach { $0.hide() }
}
private init(_ text: String) {
private func setupBlurView() {
blurView.layer.setCorner(radius: 8)
blurView.clipsToBounds = true
blurView.alpha = 0
let label = UILabel()
label.text = text
label.textAlignment = .center
label.numberOfLines = 0
label.font = .regular14()
label.textColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
blurView.contentView.addSubview(label)
blurView.isUserInteractionEnabled = false
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: blurView.contentView.leadingAnchor, constant: 8),
label.trailingAnchor.constraint(equalTo: blurView.contentView.trailingAnchor, constant: -8),
label.topAnchor.constraint(equalTo: blurView.contentView.topAnchor, constant: 8),
label.bottomAnchor.constraint(equalTo: blurView.contentView.bottomAnchor, constant: -8)
])
}
deinit {
timer?.invalidate()
}
}
// MARK: - Public methods
extension Toast {
@objc static func hideAll() {
toasts.forEach { $0.hide() }
}
@objc func show() {
show(in: UIApplication.shared.keyWindow, alignment: .bottom)
show(in: UIApplication.shared.keyWindow, alignment: .bottom, duration: Toast.duration)
}
@objc func show(withAlignment alignment: Alignment, pinToSafeArea: Bool = true) {
show(in: UIApplication.shared.keyWindow, alignment: alignment, pinToSafeArea: pinToSafeArea)
@objc func show(withAlignment alignment: Alignment, pinToSafeArea: Bool = true, duration: TimeInterval = Toast.duration) {
show(in: UIApplication.shared.keyWindow, alignment: alignment, pinToSafeArea: pinToSafeArea, duration: duration)
}
@objc func show(in view: UIView?, alignment: Alignment, pinToSafeArea: Bool = true) {
@objc func show(in view: UIView?, alignment: Alignment, pinToSafeArea: Bool = true, duration: TimeInterval = Toast.duration) {
guard let view = view else { return }
blurView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(blurView)
@ -85,7 +74,7 @@ final class Toast: NSObject {
self.blurView.alpha = 1
}
timer = Timer.scheduledTimer(timeInterval: 3,
timer = Timer.scheduledTimer(timeInterval: duration,
target: self,
selector: #selector(hide),
userInfo: nil,
@ -102,3 +91,46 @@ final class Toast: NSObject {
}
}
}
extension Toast {
@objc static func toast(withText text: String) -> Toast {
DefaultToast(text)
}
@objc static func undoToast(withText text: String, undoAction: @escaping () -> Void) -> Toast {
UndoToast(text, undoAction: undoAction)
}
}
private final class DefaultToast: Toast {
private let messageLabel = UILabel()
fileprivate convenience init(_ text: String) {
self.init()
setupMessageLabel(text)
layoutViews()
}
private func setupMessageLabel(_ text: String) {
messageLabel.text = text
messageLabel.textAlignment = .center
messageLabel.numberOfLines = 0
messageLabel.font = .regular14()
messageLabel.textColor = .white
messageLabel.isUserInteractionEnabled = false
}
private func layoutViews() {
contentView.addSubview(messageLabel)
messageLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
messageLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8),
messageLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8),
messageLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
messageLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8)
])
}
}