Created
July 6, 2017 13:45
-
-
Save astrokin/77ec43dc3261c99209e56381133d4ef3 to your computer and use it in GitHub Desktop.
Alert Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
typealias VoidClosure = () -> Void | |
typealias AlertAction = (title: String, action: VoidClosure?, style: UIAlertActionStyle) | |
final class AlertService { | |
static let shared = AlertService() | |
fileprivate(set) lazy var alertControllerStyle: UIAlertControllerStyle = .alert | |
let errorTitle: String | |
let okTitle: String | |
let cancelTitle: String | |
init(errorTitle: String = "Error", | |
okTitle: String = "OK", | |
cancel: String = "Cancel") { | |
self.errorTitle = errorTitle | |
self.okTitle = okTitle | |
cancelTitle = cancel | |
} | |
func showMessage(_ message: String, title: String? = nil, onDismiss: (() -> Void)? = nil) { | |
showMessage(message, title: title, actions: nil, onDismiss: onDismiss) | |
} | |
func showErrorMessage(_ message: String, onDismiss: (() -> Void)? = nil) { | |
showMessage(message, title: errorTitle, actions: nil, onDismiss: onDismiss) | |
} | |
func showMessage(_ message: String?, | |
title: String?, | |
actions: [AlertAction]?, | |
preferredStyle: UIAlertControllerStyle = .actionSheet, | |
presenter: UIViewController? = UIApplication.topViewController, | |
onDismiss: (() -> Void)? = nil) { | |
let alertController = alertControllerWith(message, title: title, actions: actions, preferredStyle: preferredStyle, onDismiss: onDismiss) | |
if let _presenter = presenter { | |
_presenter.present(alertController, animated: true, completion: nil) | |
} | |
} | |
} | |
// MARK: - Private | |
private extension AlertService { | |
func alertControllerWith(_ message: String?, title: String?, actions: [AlertAction]?, | |
preferredStyle: UIAlertControllerStyle = .actionSheet, onDismiss: (() -> Void)? = nil) -> UIAlertController { | |
let alert = UIAlertController(title: title, message: message, preferredStyle: preferredStyle) | |
alert.loadViewIfNeeded() | |
if let actArray = actions { // map actions | |
actArray.forEach { title, alertAction, style in | |
let action = UIAlertAction(title: title, style: UIAlertActionStyle(rawValue: style.rawValue) ?? .default, handler: { (_) -> Void in | |
alertAction?() | |
alert.dismiss(animated: true, completion: onDismiss) | |
}) | |
alert.addAction(action) | |
} | |
} else { // add ok button if there is no actions | |
let okAction = UIAlertAction(title: okTitle, style: .default) { (_) -> Void in | |
alert.dismiss(animated: true, completion: onDismiss) | |
} | |
alert.addAction(okAction) | |
} | |
return alert | |
} | |
} | |
// MARK: - Top view controller | |
extension UIApplication { | |
static var topViewController: UIViewController? { | |
return UIApplication.shared.topViewController | |
} | |
var topViewController: UIViewController? { | |
guard let rootController = keyWindow?.rootViewController else { | |
return nil | |
} | |
return UIViewController.topViewController(rootController) | |
} | |
} | |
// MARK: - Top view controller | |
extension UIViewController { | |
static func topViewController(_ viewController: UIViewController) -> UIViewController { | |
guard let presentedViewController = viewController.presentedViewController else { | |
return viewController | |
} | |
if let navigationController = presentedViewController as? UINavigationController { | |
if let visibleViewController = navigationController.visibleViewController { | |
return topViewController(visibleViewController) | |
} | |
} else if let tabBarController = presentedViewController as? UITabBarController { | |
if let selectedViewController = tabBarController.selectedViewController { | |
return topViewController(selectedViewController) | |
} | |
} | |
return topViewController(presentedViewController) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment