假设一个新的iOS项目,只需要一个导航控制器(正确连接为入口点)和一个包含以下三行代码的重写viewDidAppear():
self.presentViewController(UIViewController(), animated: true, completion: nil)
self.dismissViewControllerAnimated(true, completion: {})
self.presentViewController(UIViewController(), animated: true, completion: nil)
执行时,该代码将发出警告“在演示文稿正在进行时尝试呈现UIViewController!”当试图呈现第二个控制器时。
问题:在调用另一个控制器之前,为了正确解除控制器,我到底错过了什么?
您需要在初始presentViewController调用上添加某种延迟,如下所示:
override func viewDidAppear(animated: Bool) {
presentViewController(UIViewController(), animated: true) { () -> Void in
self.delay(0.1, closure: { () -> () in
self.dismissViewControllerAnimated(true, completion: nil)
})
}
}
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
似乎在动画真正完成之前调用了完成块。
假设您想要显示主控制器,显示控制器,关闭控制器,再次出现并解除,然后您需要将操作链接起来,以便它们按顺序发生。
为了防止它永远旋转,您还需要仅在主控制器第一次出现时运行代码。
我不是快速的编码器,但是类似下面的东西应该可行。有一个检查以确保控制器正在被呈现或被按下,然后它使用每个操作完成来运行序列以开始下一个。这个后卫应该确保在viewDidAppear
被召唤时,在每次解雇之后,在这些情况下它没有做任何事情。
var firstTime = true;
func presentThenDismiss(finalCompletion: (() -> Void)?)
{
presentViewController(UIViewController(), animated: true, completion : { [weak self] Void in
// On completion of the present, we dismiss it
dispatch_async(dispatch_get_main_queue(), {
self?.dismissViewControllerAnimated(true, completion: { Void in
// On completion of the dismiss, we present another
finalCompletion!()
})
})
})
}
override func viewDidLoad() {
super.viewDidLoad()
// We only run the modal presentation code when being presented or
// being pushed on, NOT when exposed by a model dismiss or pop
//
if (firstTime){
firstTime = false;
self.presentThenDismiss { () -> Void in
self.presentThenDismiss { () -> Void in
}
}
}
}