mirror of
https://github.com/bitwarden/ios.git
synced 2025-12-12 07:43:01 -06:00
71 lines
2.7 KiB
Swift
71 lines
2.7 KiB
Swift
import OSLog
|
|
import UIKit
|
|
|
|
// MARK: - AlertPresentable
|
|
|
|
/// Protocol for creating and presenting a `UIAlertController` from an `Alert`.
|
|
///
|
|
@MainActor
|
|
public protocol AlertPresentable {
|
|
/// The root view controller that the alert should be presented on.
|
|
var rootViewController: UIViewController? { get }
|
|
|
|
/// Presents a `UIAlertController` created from the `Alert` on the provided `rootViewController`.
|
|
///
|
|
/// - Parameter alert: The `Alert` used to create a `UIAlertController` to present.
|
|
///
|
|
func present(_ alert: Alert)
|
|
|
|
/// Presents a `UIAlertController` created from the `Alert` on the provided `rootViewController`.
|
|
///
|
|
/// - Parameters:
|
|
/// - alert: The `Alert` used to create a `UIAlertController` to present.
|
|
/// - onDismissed: An optional closure that is called when the alert is dismissed.
|
|
///
|
|
func present(_ alert: Alert, onDismissed: (() -> Void)?)
|
|
}
|
|
|
|
public extension AlertPresentable {
|
|
/// Presents a `UIAlertController` created from the `Alert` on the provided `rootViewController`.
|
|
///
|
|
/// - Parameter alert: The `Alert` used to create a `UIAlertController` to present.
|
|
///
|
|
func present(_ alert: Alert) {
|
|
present(alert, onDismissed: nil)
|
|
}
|
|
|
|
/// Presents a `UIAlertController` created from the `Alert` on the provided `rootViewController`.
|
|
///
|
|
/// - Parameters:
|
|
/// - alert: The `Alert` used to create a `UIAlertController` to present.
|
|
/// - onDismissed: An optional closure that is called when the alert is dismissed.
|
|
///
|
|
func present(_ alert: Alert, onDismissed: (() -> Void)?) {
|
|
guard let parent = rootViewController?.topmostViewController() else { return }
|
|
|
|
// Prevent presenting alerts on alerts.
|
|
guard !(parent is UIAlertController) else {
|
|
Logger.application.error("⛔️ Error: attempted to present an alert on top of another alert!")
|
|
return
|
|
}
|
|
|
|
let alertController = alert.createAlertController(onDismissed: onDismissed)
|
|
if alert.preferredStyle == .actionSheet {
|
|
// iPadOS requires an anchor for action sheets. This solution keeps the iPad app from crashing, and centers
|
|
// the presentation of the action sheet.
|
|
alertController.popoverPresentationController?.sourceView = parent.view
|
|
alertController.popoverPresentationController?.sourceRect = CGRect(
|
|
x: parent.view.bounds.midX,
|
|
y: parent.view.bounds.midY,
|
|
width: 0,
|
|
height: 0,
|
|
)
|
|
alertController.popoverPresentationController?.permittedArrowDirections = []
|
|
}
|
|
|
|
parent.present(alertController, animated: UI.animated)
|
|
}
|
|
}
|
|
|
|
extension UIWindow: AlertPresentable {}
|