【问题标题】:Attempt to present ViewController which is already presenting (null)尝试呈现已经呈现的 ViewController (null)
【发布时间】:2015-04-21 14:32:19
【问题描述】:

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

【问题讨论】:

    标签: swift ios8


    【解决方案1】:

    因此,我尝试了很多关于 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()})
    }
    

    现在正在执行所需的序列,没有问题。希望这对其他人有帮助。

    【讨论】:

      【解决方案2】:

      另一种方法是您可以要求 GCD 延迟您的下一个演示文稿,如下所示:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-20
        • 2017-05-24
        • 1970-01-01
        • 2014-10-02
        • 2016-11-29
        • 1970-01-01
        • 2021-11-05
        • 1970-01-01
        相关资源
        最近更新 更多