场景:用户点击视图控制器上的按钮。视图控制器是导航堆栈中最顶层的(很明显)。tap调用在另一个类上调用的实用程序类方法。这里发生了不好的事情我想在控件返回到视图控制器之前在那里显示一个警告。
+ (void)myUtilityMethod {
// do stuff
// something bad happened, display an alert.
}
这是可能的UIAlertView(但可能不太合适)。
在这种情况下,你如何在myUtilityMethod中呈现UIAlertController ?
如果有人感兴趣,我创建了一个Swift 3版本的@agilityvision答案。代码:
import Foundation
import UIKit
extension UIAlertController {
var window: UIWindow? {
get {
return objc_getAssociatedObject(self, "window") as? UIWindow
}
set {
objc_setAssociatedObject(self, "window", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
open override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.window?.isHidden = true
self.window = nil
}
func show(animated: Bool = true) {
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = UIViewController(nibName: nil, bundle: nil)
let delegate = UIApplication.shared.delegate
if delegate?.window != nil {
window.tintColor = delegate!.window!!.tintColor
}
window.windowLevel = UIApplication.shared.windows.last!.windowLevel + 1
window.makeKeyAndVisible()
window.rootViewController!.present(self, animated: animated, completion: nil)
self.window = window
}
}
你可以用Swift 2.2做以下事情:
let alertController: UIAlertController = ...
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
Swift 3.0:
let alertController: UIAlertController = ...
UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
@agilityvision的回答非常好。我有在swift项目中使用的感觉,所以我想我将分享我使用swift 3.0的答案
fileprivate class MyUIAlertController: UIAlertController {
typealias Handler = () -> Void
struct AssociatedKeys {
static var alertWindowKey = "alertWindowKey"
}
dynamic var _alertWindow: UIWindow?
var alertWindow: UIWindow? {
return objc_getAssociatedObject(self, &AssociatedKeys.alertWindowKey) as? UIWindow
}
func setAlert(inWindow window: UIWindow) {
objc_setAssociatedObject(self, &AssociatedKeys.alertWindowKey, _alertWindow, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
func show(completion: Handler? = nil) {
show(animated: true, completion: completion)
}
func show(animated: Bool, completion: Handler? = nil) {
_alertWindow = UIWindow(frame: UIScreen.main.bounds)
_alertWindow?.rootViewController = UIViewController()
if let delegate: UIApplicationDelegate = UIApplication.shared.delegate, let window = delegate.window {
_alertWindow?.tintColor = window?.tintColor
}
let topWindow = UIApplication.shared.windows.last
_alertWindow?.windowLevel = topWindow?.windowLevel ?? 0 + 1
_alertWindow?.makeKeyAndVisible()
_alertWindow?.rootViewController?.present(self, animated: animated, completion: completion)
}
fileprivate override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
_alertWindow?.isHidden = true
_alertWindow = nil
}
}