视图控制器似乎进行了两次转换

6

问题概要

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

我已经研究过这个问题,并发现了加载两次的问题,但没有一个与我转换两次但只加载一次的情况相符。常见问题,比如在storyboard中添加了两个segue,在我的项目中并没有出现:

enter image description here

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

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

当用户滑动手势时,它会触发一个函数来调用一个segue到我的下一个VC。问题是,该VC转换出现两次,然后一切正常。没有任何破坏或崩溃。如果我点击我的自定义返回按钮,返回到mainVC的解开只出现一次。
揭示原因的实验
这里有个奇怪的部分: 为了理解所理解的内容,我插入了一些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运行。它显示"did nothing",因为在我的prepareForSegue中,它检查哪个segue正在运行,有时候会传递一些代码。在这种情况下,prepareForSegue什么也不做,只打印那一行。

第二行是第二个视图控制器的viewDidLoad运行。

第三行对我来说似乎怪怪的,顺序不对。这个println在mainVC中,从被pan手势调用的函数中打印出来,这就是触发第一个segue的函数。为什么这个不会在第二个VC的viewDidLoad之前打印出来呢?

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

第四行是mainVC的prepareForSegue第二次运行。然而,即使我看到过渡发生了两次,但我并没有看到控制台打印第二个viewDidLoad。

有什么能导致这种奇怪行为的想法,或者至少有什么技巧可以停止这种行为吗?


你是否在源视图控制器中的任何地方访问了目标视图控制器的视图?这会在segue之前触发它的加载。 - user4151918
你是指通过协议或其他方式吗?无论如何,我认为答案是否定的。我没有传递任何数据(因此不需要prepareForSegue代码),第二个视图控制器除其内部的UICollectionView外不符合任何委托。 - Dave G
4个回答

11

我曾经有过类似的问题,我的第二个视图控制器滑动了两次。问题出在我的 Main.storyboard 中的那个转场箭头上。我从第一个视图控制器中的按钮进行了控制拖动,而不是从我的视图控制器(每个视图控制器顶部的小黄圆圈)进行控制拖动,因此我删除了那个转场箭头,并从 VC 黄色圆圈控制拖动到我的第二个视图控制器,这样问题就解决了。

此外,这就是我使用 performSegue 函数的方式:

@IBAction func toSignUp(_ sender: Any) {
    performSegue(withIdentifier: "signUp", sender: nil)
}
希望这对您有所帮助。

请在此处查看可视化表示 https://dev59.com/F47ea4cB1Zd3GeqPDZ3l#60609511 - Rohit Singh

1
可能的一个原因是被推送的控制器在其viewWillAppear()方法中有另一个转换。
在我的情况下,我将textField.becomesFirstResponder()放在viewWillAppear()方法中,这会触发键盘显示。
将任何这样的方法移动到viewDidAppear()中。

0

我发现Elena在这个帖子Pushing View Controller Twice中的回答是一个省时的快速修复方法,只需检查导航控制器是否已经包含您要推送到的ViewController。

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

}


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接