尝试呈现已经呈现的 ViewController (null)
Attempt to present ViewController which is already presenting (null)
我正在创建用户并在使用 Facebook SDK 后登录用户。一切都应该正确地将用户插入数据库。然后我想显示一个警报,并在解除警报后,我想加载一个不同的故事板(基本上是主菜单)。
现在我的理解是错误是线程问题。但是.. 我正在将情节提要等的加载作为一个块传递给警报。那么它不应该只在用户解除警报后才被调用吗?我也尝试在主线程上设置它 运行(提到 here),但我仍然收到错误。
我在这里错过了什么?
The originating call:
if DBUser.insertDictionary(user.getModelAsStringDictionary()) {
if DBUser.loginUserWithFacebookId(facebookId!){
self.accountCreatedAlert()
}else{
//log error, user could not be logged in.
}
}else{
// log error user account could not be inserted into the database
}
}
警告文本和 switchToMainStoryboard() 方法的异步绑定:
private func accountCreatedAlert(fn:()){
let asyncMoveToMain = {dispatch_async(dispatch_get_main_queue()) {
self.switchToMainStoryboard()
}}
self.showAlert("You will now be logged in", title: "Account created", fn: asyncMoveToMain)
}
警报:
func showAlert(text : NSString, title : NSString, fn:()->Void){
var alert = UIAlertController(title: title, message: text, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
UIApplication.sharedApplication().delegate?.window!?.rootViewController?.presentViewController(alert, animated: true, completion: fn)
}
故事板的加载位置:
func switchToMainStoryboard() ->Void{
let main = UIStoryboard(name: "Main", bundle: nil)
var viewController = main.instantiateInitialViewController() as UIViewController
viewController.modalTransitionStyle = UIModalTransitionStyle.CoverVertical
self.presentViewController(viewController, animated: true, completion: nil)
}
所以我尝试了很多乱七八糟的 dispatch_async 和 dispatch_sync 方法,每次,无论我做了什么,我都得到了冻结 UI 的锁定条件.
在进一步检查文档(和我的代码)后,我将块提供给 AlertControllerAction 而不是 presentViewController。感谢 this post 提供语法。产生的变化如下:
// MARK: Alert Related Methods
func showAlert(text : NSString, title : NSString, fn:()->Void){
var alert = UIAlertController(title: title, message: text, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {(alert: UIAlertAction!) in fn()}))
UIApplication.sharedApplication().delegate?.window!?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
}
然后开始这样称呼它:
private func showAccountCreatedAlertThenLoadMainStoryboard(){
self.showAlert("You will now be logged in", title: "Account created", fn: {self.switchToMainStoryboard()})
}
所需的顺序现在正在顺利进行。希望这对其他人有帮助。
另一种方法是您可以要求 GCD 延迟您的下一次演示,如下所示:
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
// next present
}
我正在创建用户并在使用 Facebook SDK 后登录用户。一切都应该正确地将用户插入数据库。然后我想显示一个警报,并在解除警报后,我想加载一个不同的故事板(基本上是主菜单)。
现在我的理解是错误是线程问题。但是.. 我正在将情节提要等的加载作为一个块传递给警报。那么它不应该只在用户解除警报后才被调用吗?我也尝试在主线程上设置它 运行(提到 here),但我仍然收到错误。
我在这里错过了什么?
The originating call:
if DBUser.insertDictionary(user.getModelAsStringDictionary()) {
if DBUser.loginUserWithFacebookId(facebookId!){
self.accountCreatedAlert()
}else{
//log error, user could not be logged in.
}
}else{
// log error user account could not be inserted into the database
}
}
警告文本和 switchToMainStoryboard() 方法的异步绑定:
private func accountCreatedAlert(fn:()){
let asyncMoveToMain = {dispatch_async(dispatch_get_main_queue()) {
self.switchToMainStoryboard()
}}
self.showAlert("You will now be logged in", title: "Account created", fn: asyncMoveToMain)
}
警报:
func showAlert(text : NSString, title : NSString, fn:()->Void){
var alert = UIAlertController(title: title, message: text, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
UIApplication.sharedApplication().delegate?.window!?.rootViewController?.presentViewController(alert, animated: true, completion: fn)
}
故事板的加载位置:
func switchToMainStoryboard() ->Void{
let main = UIStoryboard(name: "Main", bundle: nil)
var viewController = main.instantiateInitialViewController() as UIViewController
viewController.modalTransitionStyle = UIModalTransitionStyle.CoverVertical
self.presentViewController(viewController, animated: true, completion: nil)
}
所以我尝试了很多乱七八糟的 dispatch_async 和 dispatch_sync 方法,每次,无论我做了什么,我都得到了冻结 UI 的锁定条件.
在进一步检查文档(和我的代码)后,我将块提供给 AlertControllerAction 而不是 presentViewController。感谢 this post 提供语法。产生的变化如下:
// MARK: Alert Related Methods
func showAlert(text : NSString, title : NSString, fn:()->Void){
var alert = UIAlertController(title: title, message: text, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {(alert: UIAlertAction!) in fn()}))
UIApplication.sharedApplication().delegate?.window!?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
}
然后开始这样称呼它:
private func showAccountCreatedAlertThenLoadMainStoryboard(){
self.showAlert("You will now be logged in", title: "Account created", fn: {self.switchToMainStoryboard()})
}
所需的顺序现在正在顺利进行。希望这对其他人有帮助。
另一种方法是您可以要求 GCD 延迟您的下一次演示,如下所示:
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
// next present
}