ViewController 出现两次转换

ViewController Appears to Transition Twice

问题总结

我的主要VC --> 第二个 VC 转换出现到 运行 两次。然而,奇怪的是第二个 VC 的 viewDidLoad 只 运行 一次。这是我项目中唯一有这个问题的转换。

我对此进行了研究并发现了加载两次的问题,但 none 与我的转换两次但加载一次的场景相匹配。常见问题,比如有人在故事板中添加了两个 segues,没有出现在我的项目中:

在我的 first/root 视图控制器(称为 mainVC)中,我以编程方式在 viewDidLoad 中添加了一个边缘平移手势:

        let panLeftEdgeGesture_MainVC = UIScreenEdgePanGestureRecognizer(target: self, action: "panLeftEdge_toLifeList:")
        panLeftEdgeGesture_MainVC.edges = .Left
        view.addGestureRecognizer(panLeftEdgeGesture_MainVC)

当用户滑动那个平移手势时,它会触发一个调用 segue 到我的下一个 VC 的函数。问题是,VC 转换出现两次,然后一切正常。没有任何损坏或崩溃。如果我单击我的自定义后退按钮,返回主VC 只会出现一次。

揭示原因的实验

这是奇怪的部分:为了理解所理解的内容,我插入了一些 println 代码,这是控制台打印的内容:

No matching prepareForSegue: So did nothing to prepare.
LifeList_CollectionView viewDidLoad did run
Pan segue from mainVC to Life Lists did run
No matching prepareForSegue: So did nothing to prepare.

第一行是 prepareForSegue 运行ning。它说 "did nothing" 因为在我的 prepareForSegue 中它检查哪个 segue 是 运行ning 并且有时它会传递一些代码。在这种情况下,prepareForSegue 只打印该行。

第二行是第二个VC的viewDidLoad 运行ning.

第三行对我来说似乎很奇怪而且乱七八糟,但我不是专家。 println 在 mainVC 中,并从平移手势调用的函数打印,这是首先触发 segue 的函数。为什么这不会在第二个 VC 的 viewDidLoad 之前打印?:

func panLeftEdge_toLifeList(sender: UIScreenEdgePanGestureRecognizer) {
    performSegueWithIdentifier("segueToLifeLists", sender: nil)
    println("Pan segue from mainVC to Life Lists did run")
}

第四行是mainVC的第二次prepareForSegue 运行ning。但是,我没有看到控制台打印第二个 viewDidLoad,即使在视觉上我看到转换发生了两次。

知道什么会导致这种奇怪的行为,或者至少有什么技巧可以阻止这种行为吗?

基本上你只需要重命名目标视图控制器的class。

完整答案见此post:

我遇到了几乎相同的问题,我的第二个 VC 滑动了两次。问题出在我的 Main.storyboard 中的那个 segue 箭头。我 control-dragged 来自第一个 VC 中的按钮而不是来自我的 VC(每个 VC 顶部的黄色小圆圈),所以我删除了那个 segue 箭头和 control-dragged 从 VC 黄色圆圈到我的第二个 VC 并解决了问题。

这也是我使用 performSegue 函数的方式:

@IBAction func toSignUp(_ sender: Any) {
    performSegue(withIdentifier: "signUp", sender: nil)
}

希望这对您有所帮助。

一个原因可能是被推送的控制器在其 viewWillAppear() 方法中有另一个转换。

在我的例子中,我将 textField.becomesFirstResponder() 放入 viewWillAppear() 触发键盘显示的方法中

将任何此类方法移至 viewDidAppear()

我发现 Elena 的回答(在此线程 Pushing View Controller Twice 上)是一种节省时间的快速修复方法,只需检查导航控制器是否已包含您要推送到的 ViewController。

if !(self.navigationController!.viewControllers.contains(editView)){
self.navigationController?.pushViewController(editView, animated:true)

}