在不使用performSegueWithIdentifier的情况下,当我点击一个按钮时prepareForSegue方法没有被调用

28

我正在学习斯坦福大学的iOS课程,并尝试制作模态视图控制器。在演示中,他们有一个按钮可以启动模态视图,当单击它时,函数prepareForSegue将被调用。我复制了代码并将其实现到我的项目中,唯一的区别是我的演示是在iPhone故事板上,而他们的演示是在iPad上。

我注意到,当我的模态视图控制器出现时,它不会在此之前调用prepareForSegue。我搜索了斯坦福项目,看看他们在调用prepareForSegue之前是否注册了任何segue行为,但没有找到任何证据。有人可以帮忙解决吗?我在Stack Overflow上搜索,发现用户都缺少了performSegueWithIdentifier的调用实现,然而,在斯坦福的演示中他们从未这样做。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier hasPrefix:@"Create Label"]) {
        AskerViewController *asker = (AskerViewController *)segue.destinationViewController;
        asker.question = @"What do you want your label to say?";
        asker.answer = @"Label Text";
        asker.delegate = self;
    }

}

以下是一个Storyboard的示例: enter image description here

这是我的Storyboard示例: enter image description here

在调试器中,当我在Stanford Demo代码中停止时,调用堆栈显示Storyboard正在执行segue操作,我需要在我的Storyboard中配置什么才能实现同样的结果? enter image description here


1
你怎么知道 prepareForSegue: 没有被调用?我敢打赌它一定被调用了。唯一确定的方法是在其中的第一条语句上设置断点。你这样做了吗? - matt
1
是的,我有这个问题,所以我才在问。在我的演示中,我的prepreForSegue没有被调用,但在斯坦福的演示中它被调用了。 - Amro Younes
10个回答

35

事实证明,我的视图控制器中,按钮调用模态视图时没有正确的类来实现prepareForSegue方法。这是默认的UIViewController而不是我的自定义类。

我发现的方法是在viewDidLoad中设置断点,但即使如此也没有停止,因此我怀疑在storyboard中,我没有将正确的类与实现按钮的视图相关联。


12
做得好!你学到了重要的东西!这是一个容易犯的错误,你以后还会犯很多次。:)))) - matt
我不想承认,我以前犯过这个错误。我简直不敢相信我花了一段时间才弄清楚这个问题! - Amro Younes

15

对于有这个问题的其他人,如果你现在使用的是Swift 3,拥有以下函数将不会抛出错误,因为它是正确的语法,但它将无法工作,因为它是Swift 2函数:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // code
}

你必须更新到Swift 3的“prepare”函数,才能使它适用于转场:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

1
当Swift 2的方法在Swift 3中不兼容且表现不同的时候,苹果公司发出某种警告或错误会有所帮助。不幸的是,这并不是事实,感谢您的答案,它起作用了。 - Naishta
谢谢!非常有帮助 +1 - ICL1901

11

当为表格视图连接自动跳转时,除了Amro的答案(没有分配相应的子类),还有另外两种情况可能导致prepareForSegue未被调用。确保你已经:

  1. 从表格视图原型单元格而不是表格视图控制器中连接了segue。

  2. 在segue连接弹出菜单中使用“选择Segue”组下的segue,而不是“附加操作”下的segue。

连接自动segue

[点击图像放大]


就此而言,附加操作是关于 等等的。更多信息请参见 http://www.imaladec.com/upload-files/images/Examples/TableView/DetailsCellsTableView/DetailsCells_01.jpg。 - mfaani

5
无论是模态转场还是推送转场,下面的代码都会被调用。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"Create Label"]) {
        SignUpViewController *asker = segue.destinationViewController;
    }
}

不,从uitableview导航并不总是起作用。 - Code cracker

2
在我的情况下,这是因为我的控制器继承了另一个控制器(Eureka表单视图控制器= FormViewController),它实现了如下的performSegue函数:
open override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

我的函数是这样实现的:

func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

为了解决这个问题,我只需在之前添加override:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

看这里!


2

我曾经遇到一个与 UICollectionViewCell 作为segue来源的类似问题。
看起来,如果要使storyboard segue正常工作(不需要使用performSegueWithIdentifier),你需要创建一个自定义的UICollectionViewCell子类,并在storyboard中将其用作CollectionViewCellClass


2

我有一个类似的问题。

思路如下:

  1. 确保你有正确的方法签名。在Swift 3中已经发生了变化。
  2. 然后确保你已经将按钮(或触发segue的任何其他元素)的连接方式与storyboard中的segue连接方式匹配。有时你会调用一个按钮,但没有正确地将该segue从该按钮连接到目标视图控制器。
  3. 确保segue的标识符是正确的。虽然这不是prepareForSegue未被调用的原因,但只是特定segue未被调用的原因。

对我来说,我尝试使用另一个我知道可行的segue - 然后我只需要重新创建它。思路不错。 - UKDataGeek

1
在我的情况下,我没有在包含segue的视图控制器的storyboard中将模块设置为类的名称。它被设置为无,一旦我点击了模块字段,它就会设置为正确的项目/模块,并解决了这个问题。

0
在我的情况下,我在项目中有几个视图控制器的基类。该基类实现了prepareForSegue(),但并非在每种情况下都会被调用。问题在于,在继承自基类并覆盖其prepareForSegue()实现的一个视图控制器中,我忘记调用super.prepareForSegue()

-1

首先,您必须选择按钮+ctrl拖动项目到您的视图控制器中选择选择转换。然后,您必须正确命名转换标识符。

不要将一个视图控制器连接到另一个视图控制器。 为此导入UIKit.framework 然后将调用此方法。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"identifierName"])
    {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        ExampleViewController *destViewController = segue.destinationViewController;
    }
}

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