每个 UIAlertController 在用户响应之前自动消失 - 自 iOS 13
Every UIAlertController disappear automatically before user responds - since iOS 13
因为我使用的是 iOS 13,所以我的每个 UIAlertController 都会显示大约半秒钟,然后在任何用户操作之前立即消失。有什么想法吗?
当我在我的应用程序的不同部分使用 UIAlertController 时,我使用了一个扩展,它允许我从经典视图和 collectionView(单元格,header 等...)中弹出
public extension UIAlertController {
func show() {
let win = UIWindow(frame: UIScreen.main.bounds)
let vc = UIViewController()
vc.view.backgroundColor = .clear
vc.view.tintColor = Theme.mainAccentColor
win.rootViewController = vc
win.windowLevel = UIWindow.Level.alert + 1
win.makeKeyAndVisible()
vc.present(self, animated: true, completion: nil)
}
}
这是此扩展使用的示例:
fileprivate func showMissingAlert() {
let alert = UIAlertController(title: "blablabla", message: "blablablablabla blabla", preferredStyle: UIAlertController.Style.alert)
alert.show()
alert.view.tintColor = Theme.mainAccentColor
let cancelAction = UIAlertAction(title: "OK, blabla", style: .default, handler: {(alert: UIAlertAction!) in print("ok, leave")})
alert.addAction(cancelAction)
}
在我的代码中更进一步:
showMissingAlert()
在 iOS 13 之前,每个 UIAlert 都工作正常......自从我搬到 iOS 13,甚至 iOS 13.1,它变得一团糟...... :(
知道是什么原因造成的吗?
以及如何防止将 UIAlert 用作下意识消息:) ?
我遇到了完全相同的问题,并通过将显示警报的 window 保存在强变量中来修复它。
例如,您可以在 AppDelegate 中持有一个 window 来显示警报,并在您的 UIAlertController 扩展中使用它。
//In app delegate
let alertWindow: UIWindow = {
let win = UIWindow(frame: UIScreen.main.bounds)
win.windowLevel = UIWindow.Level.alert + 1
return win
}()
然后,在您的分机中:
public extension UIAlertController {
func show() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let vc = UIViewController()
vc.view.backgroundColor = .clear
vc.view.tintColor = Theme.mainAccentColor
appDelegate.alertWindow.rootViewController = vc
appDelegate.alertWindow.makeKeyAndVisible()
vc.present(self, animated: true, completion: nil)
}
}
您还需要确保在关闭警报时从视图中移除警报 window,否则您的应用将无响应,因为所有点击都将由(不可见的)警报处理 window,这仍然是最重要的。
我通过将此代码添加到警报中所有操作的处理程序来执行此操作:
(UIApplication.shared.delegate as! AppDelegate).alertWindow.isHidden = true
基于pepsy 。
如果你不想关心alertWindow.isHidden = true stuff
,你可以这样做:
class AlertHandler {
private static let alertWindow: UIWindow = {
let window = UIWindow(frame: UIScreen.main.bounds)
window.windowLevel = UIWindow.Level.alert + 1
return window
}()
private var alertController: UIAlertController
init(title: String?,
message: String?) {
alertController = UIAlertController(title: title,
message: message,
preferredStyle: .alert)
}
func addAction(title: String?,
style: UIAlertAction.Style,
handler: ((UIAlertAction) -> Void)? = nil) {
let action = UIAlertAction(title: title,
style: style) { action in
handler?(action)
AlertHandler.alertWindow.isHidden = true
}
alertController.addAction(action)
}
func present() {
AlertHandler.alertWindow.rootViewController = UIViewController()
AlertHandler.alertWindow.makeKeyAndVisible()
AlertHandler.alertWindow.rootViewController?.present(alertController,
animated: true,
completion: nil)
}
}
您也可以试试这个解决方案。它对我有效。
在你的 class.
中写下下面的方法
func presentViewController(alertController: UIAlertController, completion: (() -> Void)? = nil) {
if var topController = UIApplication.shared.keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
DispatchQueue.main.async {
topController.present(alertController, animated: true, completion: completion)
}
}
}
然后从您的代码中调用它,如下所示
let alertController = UIAlertController(title: "Discard Photo?",
message: "Your photo will not be attached",
preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Keep Photo", style: .default, handler: nil))
alertController.addAction(UIAlertAction(title: "Discard", style: .default) { (_) -> Void in
self.PhotoStack.deletePhoto(at: index)
self.cameraBtn.isEnabled = true
})
self.presentViewController(alertController: alertController)
在您考虑在 window
中制作 alertController
之前,请检查您的动画或其他 UI 一起制作动画的东西。
例如,如果您同时执行 self.dismiss(VC)
和 self.present(alertController)
,就会出现问题
最好的开发方法不是忽略不规则的 ui 事件,而是先检查其他有问题的东西。
因为我使用的是 iOS 13,所以我的每个 UIAlertController 都会显示大约半秒钟,然后在任何用户操作之前立即消失。有什么想法吗?
当我在我的应用程序的不同部分使用 UIAlertController 时,我使用了一个扩展,它允许我从经典视图和 collectionView(单元格,header 等...)中弹出
public extension UIAlertController {
func show() {
let win = UIWindow(frame: UIScreen.main.bounds)
let vc = UIViewController()
vc.view.backgroundColor = .clear
vc.view.tintColor = Theme.mainAccentColor
win.rootViewController = vc
win.windowLevel = UIWindow.Level.alert + 1
win.makeKeyAndVisible()
vc.present(self, animated: true, completion: nil)
}
}
这是此扩展使用的示例:
fileprivate func showMissingAlert() {
let alert = UIAlertController(title: "blablabla", message: "blablablablabla blabla", preferredStyle: UIAlertController.Style.alert)
alert.show()
alert.view.tintColor = Theme.mainAccentColor
let cancelAction = UIAlertAction(title: "OK, blabla", style: .default, handler: {(alert: UIAlertAction!) in print("ok, leave")})
alert.addAction(cancelAction)
}
在我的代码中更进一步:
showMissingAlert()
在 iOS 13 之前,每个 UIAlert 都工作正常......自从我搬到 iOS 13,甚至 iOS 13.1,它变得一团糟...... :(
知道是什么原因造成的吗?
以及如何防止将 UIAlert 用作下意识消息:) ?
我遇到了完全相同的问题,并通过将显示警报的 window 保存在强变量中来修复它。
例如,您可以在 AppDelegate 中持有一个 window 来显示警报,并在您的 UIAlertController 扩展中使用它。
//In app delegate
let alertWindow: UIWindow = {
let win = UIWindow(frame: UIScreen.main.bounds)
win.windowLevel = UIWindow.Level.alert + 1
return win
}()
然后,在您的分机中:
public extension UIAlertController {
func show() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let vc = UIViewController()
vc.view.backgroundColor = .clear
vc.view.tintColor = Theme.mainAccentColor
appDelegate.alertWindow.rootViewController = vc
appDelegate.alertWindow.makeKeyAndVisible()
vc.present(self, animated: true, completion: nil)
}
}
您还需要确保在关闭警报时从视图中移除警报 window,否则您的应用将无响应,因为所有点击都将由(不可见的)警报处理 window,这仍然是最重要的。 我通过将此代码添加到警报中所有操作的处理程序来执行此操作:
(UIApplication.shared.delegate as! AppDelegate).alertWindow.isHidden = true
基于pepsy alertWindow.isHidden = true stuff
,你可以这样做:
class AlertHandler {
private static let alertWindow: UIWindow = {
let window = UIWindow(frame: UIScreen.main.bounds)
window.windowLevel = UIWindow.Level.alert + 1
return window
}()
private var alertController: UIAlertController
init(title: String?,
message: String?) {
alertController = UIAlertController(title: title,
message: message,
preferredStyle: .alert)
}
func addAction(title: String?,
style: UIAlertAction.Style,
handler: ((UIAlertAction) -> Void)? = nil) {
let action = UIAlertAction(title: title,
style: style) { action in
handler?(action)
AlertHandler.alertWindow.isHidden = true
}
alertController.addAction(action)
}
func present() {
AlertHandler.alertWindow.rootViewController = UIViewController()
AlertHandler.alertWindow.makeKeyAndVisible()
AlertHandler.alertWindow.rootViewController?.present(alertController,
animated: true,
completion: nil)
}
}
您也可以试试这个解决方案。它对我有效。
在你的 class.
中写下下面的方法func presentViewController(alertController: UIAlertController, completion: (() -> Void)? = nil) {
if var topController = UIApplication.shared.keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
DispatchQueue.main.async {
topController.present(alertController, animated: true, completion: completion)
}
}
}
然后从您的代码中调用它,如下所示
let alertController = UIAlertController(title: "Discard Photo?",
message: "Your photo will not be attached",
preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Keep Photo", style: .default, handler: nil))
alertController.addAction(UIAlertAction(title: "Discard", style: .default) { (_) -> Void in
self.PhotoStack.deletePhoto(at: index)
self.cameraBtn.isEnabled = true
})
self.presentViewController(alertController: alertController)
在您考虑在 window
中制作 alertController
之前,请检查您的动画或其他 UI 一起制作动画的东西。
例如,如果您同时执行 self.dismiss(VC)
和 self.present(alertController)
,就会出现问题
最好的开发方法不是忽略不规则的 ui 事件,而是先检查其他有问题的东西。