尝试呈现已经呈现的ViewController(null)

时间:2015-02-20 01:11:16

标签: swift ios8

我正在创建用户并在使用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)
}

2 个答案:

答案 0 :(得分:0)

所以我尝试了很多关于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()})
}

现在所需的序列没有问题。希望这有助于其他人。

答案 1 :(得分:-2)

另一种方式是,您可以要求GCD延迟您的下一次演示,如下所示:

    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
    // next present
}