Die Antwort von Zev Eisenberg ist einfach und unkompliziert, funktioniert jedoch nicht immer und kann mit dieser Warnmeldung fehlschlagen:
Warning: Attempt to present <UIAlertController: 0x7fe6fd951e10>
on <ThisViewController: 0x7fe6fb409480> which is already presenting
<AnotherViewController: 0x7fe6fd109c00>
Dies liegt daran, dass sich der Windows-RootViewController nicht oben in den dargestellten Ansichten befindet. Um dies zu korrigieren, müssen wir die Präsentationskette durchlaufen, wie in meinem in Swift 3 geschriebenen UIAlertController-Erweiterungscode gezeigt:
/// show the alert in a view controller if specified; otherwise show from window's root pree
func show(inViewController: UIViewController?) {
if let vc = inViewController {
vc.present(self, animated: true, completion: nil)
} else {
// find the root, then walk up the chain
var viewController = UIApplication.shared.keyWindow?.rootViewController
var presentedVC = viewController?.presentedViewController
while presentedVC != nil {
viewController = presentedVC
presentedVC = viewController?.presentedViewController
}
// now we present
viewController?.present(self, animated: true, completion: nil)
}
}
func show() {
show(inViewController: nil)
}
Updates am 15.09.2017:
Getestet und bestätigt, dass die obige Logik im neu verfügbaren GM-Seed für iOS 11 immer noch hervorragend funktioniert. Die von Agilityvision am besten gewählte Methode funktioniert jedoch nicht: Die Alarmansicht wird in einer neu geprägten dargestelltUIWindow
befindet sich unter der Tastatur und verhindert möglicherweise, dass der Benutzer auf seine Schaltflächen tippt. Dies liegt daran, dass in iOS 11 alle Fensterebenen, die höher als die des Tastaturfensters sind, auf eine darunter liegende Ebene abgesenkt werden.
Ein Artefakt der Präsentation von keyWindow
obwohl ist die Animation der Tastatur, die nach unten rutscht, wenn eine Warnung angezeigt wird, und wieder nach oben, wenn die Warnung geschlossen wird. Wenn Sie möchten, dass die Tastatur während der Präsentation dort bleibt, können Sie versuchen, sie im oberen Fenster selbst zu präsentieren, wie im folgenden Code gezeigt:
func show(inViewController: UIViewController?) {
if let vc = inViewController {
vc.present(self, animated: true, completion: nil)
} else {
// get a "solid" window with the highest level
let alertWindow = UIApplication.shared.windows.filter { $0.tintColor != nil || $0.className() == "UIRemoteKeyboardWindow" }.sorted(by: { (w1, w2) -> Bool in
return w1.windowLevel < w2.windowLevel
}).last
// save the top window's tint color
let savedTintColor = alertWindow?.tintColor
alertWindow?.tintColor = UIApplication.shared.keyWindow?.tintColor
// walk up the presentation tree
var viewController = alertWindow?.rootViewController
while viewController?.presentedViewController != nil {
viewController = viewController?.presentedViewController
}
viewController?.present(self, animated: true, completion: nil)
// restore the top window's tint color
if let tintColor = savedTintColor {
alertWindow?.tintColor = tintColor
}
}
}
Der einzige nicht so große Teil des obigen Codes ist, dass er den Klassennamen überprüft UIRemoteKeyboardWindow
, um sicherzustellen, dass wir ihn auch einschließen können. Trotzdem funktioniert der obige Code hervorragend in iOS 9, 10 und 11 GM-Seeds, mit der richtigen Farbtonfarbe und ohne die Artefakte der Tastatur.