UIAlertController 阻止 segue 执行(“window 不等于视图的 window”)
UIAlertController keeps segue from performing ("window is not equal to view’s window“)
在我的应用程序中添加 UIAlertController
以在执行某些设置时显示进度对话框后,segue 不再执行到第二个 ViewController
的切换(参见问题 here - 事实证明罪魁祸首不是我最初认为的那样,这就是我提出一个新问题的原因)。
所以现在我使用 Swift 5、Xcode 10 和 iOS 12 设置了一个测试项目,我也遇到了同样的问题:
描述:
- ViewController1:有一个 "Login" 按钮调用
onClickLoginButton
- NavigationController: 通过 "segue12" 连接到 VC1(我从黄色 "ViewController" 图标中拖动)
- ViewController2:我通过 "Embed in" 添加了 NC;有一个
UITableView
- 单击 "Login" 按钮会显示
UIAlertController
,然后应执行转至 VC2。相反,它只在控制台中输出一条消息(请参阅下面的 "console output")并保持 VC1 加载。
故事板:
ViewController1:
class ViewController: UIViewController {
@IBOutlet weak var loginButton: UIButton!
var alert:UIAlertController!
var alertMessage:String = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func onClickLoginButton(_ sender: Any) {
setUpDialog()
}
private func setUpDialog() {
alertMessage = "Logging in"
alert = UIAlertController(title: "Please wait", message: alertMessage, preferredStyle: UIAlertController.Style.alert)
self.present(alert, animated: true, completion: nil)
performSegue(withIdentifier: "segue12", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("prepare 1->2a")
let navVC = segue.destination as? UINavigationController
let tableVC = navVC?.viewControllers.first as! ViewController2
tableVC.test = "Test!"
print("prepare 1->2b")
}
}
ViewController2:
class ViewController2: UIViewController, UITableViewDataSource, UITableViewDelegate {
var test:String = ""
override func viewDidLoad() {
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
return cell
}
}
控制台输出:
prepare 1->2a
prepare 1->2b
2019-05-21 13:09:16.981738+0200 SegueTest[3505:69382] <UIView: 0x7fc40fd0e790; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x600000dc3da0>>'s window is not equal to <UIAlertController: 0x7fc41180ba00>'s view's window!
将此添加到 prepare
(就在 print("prepare 1->2b")
之前)会删除对话框,但它仍会输出消息并且不会切换到第二个视图:
alert.dismiss(animated: true, completion: nil)
以上消息是什么意思(是什么原因造成的?)以及如何修复此测试应用程序,使其显示对话框,然后切换到 ViewController2?
您不能同时显示警报和进行 segue 使用 DispatchQueue.main.asyncAfter
等待
private func setUpDialog() {
alertMessage = "Logging in"
alert = UIAlertController(title: "Please wait", message: alertMessage, preferredStyle: UIAlertController.Style.alert)
self.present(alert, animated: true, completion: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.alert.dismiss(animated: true, completion: {
self.performSegue(withIdentifier: "segue12", sender: self)
})
}
}
在我的应用程序中添加 UIAlertController
以在执行某些设置时显示进度对话框后,segue 不再执行到第二个 ViewController
的切换(参见问题 here - 事实证明罪魁祸首不是我最初认为的那样,这就是我提出一个新问题的原因)。
所以现在我使用 Swift 5、Xcode 10 和 iOS 12 设置了一个测试项目,我也遇到了同样的问题:
描述:
- ViewController1:有一个 "Login" 按钮调用
onClickLoginButton
- NavigationController: 通过 "segue12" 连接到 VC1(我从黄色 "ViewController" 图标中拖动)
- ViewController2:我通过 "Embed in" 添加了 NC;有一个
UITableView
- 单击 "Login" 按钮会显示
UIAlertController
,然后应执行转至 VC2。相反,它只在控制台中输出一条消息(请参阅下面的 "console output")并保持 VC1 加载。
故事板:
ViewController1:
class ViewController: UIViewController {
@IBOutlet weak var loginButton: UIButton!
var alert:UIAlertController!
var alertMessage:String = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func onClickLoginButton(_ sender: Any) {
setUpDialog()
}
private func setUpDialog() {
alertMessage = "Logging in"
alert = UIAlertController(title: "Please wait", message: alertMessage, preferredStyle: UIAlertController.Style.alert)
self.present(alert, animated: true, completion: nil)
performSegue(withIdentifier: "segue12", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("prepare 1->2a")
let navVC = segue.destination as? UINavigationController
let tableVC = navVC?.viewControllers.first as! ViewController2
tableVC.test = "Test!"
print("prepare 1->2b")
}
}
ViewController2:
class ViewController2: UIViewController, UITableViewDataSource, UITableViewDelegate {
var test:String = ""
override func viewDidLoad() {
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
return cell
}
}
控制台输出:
prepare 1->2a
prepare 1->2b
2019-05-21 13:09:16.981738+0200 SegueTest[3505:69382] <UIView: 0x7fc40fd0e790; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x600000dc3da0>>'s window is not equal to <UIAlertController: 0x7fc41180ba00>'s view's window!
将此添加到 prepare
(就在 print("prepare 1->2b")
之前)会删除对话框,但它仍会输出消息并且不会切换到第二个视图:
alert.dismiss(animated: true, completion: nil)
以上消息是什么意思(是什么原因造成的?)以及如何修复此测试应用程序,使其显示对话框,然后切换到 ViewController2?
您不能同时显示警报和进行 segue 使用 DispatchQueue.main.asyncAfter
等待
private func setUpDialog() {
alertMessage = "Logging in"
alert = UIAlertController(title: "Please wait", message: alertMessage, preferredStyle: UIAlertController.Style.alert)
self.present(alert, animated: true, completion: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.alert.dismiss(animated: true, completion: {
self.performSegue(withIdentifier: "segue12", sender: self)
})
}
}