คำตอบของ Zev Eisenberg นั้นเรียบง่ายและตรงไปตรงมา แต่ก็ไม่ได้ผลเสมอไปและอาจล้มเหลวด้วยข้อความเตือนนี้:
Warning: Attempt to present <UIAlertController: 0x7fe6fd951e10>
on <ThisViewController: 0x7fe6fb409480> which is already presenting
<AnotherViewController: 0x7fe6fd109c00>
นี่เป็นเพราะ windows rootViewController ไม่ได้อยู่ที่ด้านบนของมุมมองที่นำเสนอ เพื่อแก้ไขสิ่งนี้เราต้องเดินตามสายงานนำเสนอดังที่แสดงในรหัสส่วนขยาย UIAlertController ของฉันที่เขียนใน Swift 3:
/// 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)
}
อัปเดตเมื่อวันที่ 15/9/2560:
ผ่านการทดสอบและยืนยันแล้วว่าตรรกะดังกล่าวยังคงใช้งานได้ดีในเมล็ดพันธุ์ iOS 11 จีเอ็มที่วางจำหน่าย อย่างไรก็ตามวิธีการโหวตสูงสุดโดย agilityvision ไม่ได้: มุมมองการแจ้งเตือนที่นำเสนอในมิ้นต์ใหม่UIWindow
อยู่ด้านล่างของคีย์บอร์ดและอาจป้องกันไม่ให้ผู้ใช้แตะที่ปุ่ม นี่เป็นเพราะใน iOS 11 window ทั้งหมดระดับที่สูงกว่าของหน้าต่างคีย์บอร์ดจะลดลงไปถึงระดับที่ต่ำกว่า
สิ่งหนึ่งที่นำเสนอจากkeyWindow
แม้ว่าเป็นภาพเคลื่อนไหวของแป้นพิมพ์เลื่อนลงเมื่อนำเสนอการแจ้งเตือนและเลื่อนขึ้นอีกครั้งเมื่อมีการแจ้งเตือนถูกไล่ออก หากคุณต้องการให้แป้นพิมพ์อยู่ในระหว่างการนำเสนอคุณสามารถลองนำเสนอจากหน้าต่างด้านบนของตัวเองดังแสดงในรหัสด้านล่าง:
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
}
}
}
ส่วนที่ไม่ใหญ่มากของโค้ดด้านบนคือตรวจสอบชื่อคลาสUIRemoteKeyboardWindow
เพื่อให้แน่ใจว่าเราสามารถใส่มันได้ด้วย อย่างไรก็ตามรหัสดังกล่าวใช้งานได้ดีใน iOS 9, 10 และ 11 จีเอ็มเมล็ดพันธุ์, ด้วยสีที่ถูกต้องและไม่มีการเลื่อนคีย์บอร์ด