从视图控制器到其本身的Storyboard Segue

79
我正在尝试制作一个机制来下钻文件/文件夹列表。我的想法是每次用户选择一个文件夹时都显示相同的文件列表视图控制器,并在选择文件时显示文件详细信息视图控制器。
到目前为止,我已经从文件列表视图控制器创建了一个segue到文件详细信息视图控制器,并从文件列表表格视图单元格创建了一个segue到文件列表表格视图控制器:

enter image description here

这个问题在于一旦用户点击单元格,就会执行segue。我想把segue从表视图单元格中移除,并从文件列表视图控制器自身创建一个segue。这样,当用户点击单元格时,我就可以通过编程方式触发正确的segue。
所以,我的问题是:是否可以在Interface Builder中从视图控制器创建到自身的segue?

1
是的,你可以使用Xcode 5。请参见帖子 - John Henckel
打开编辑器菜单,点击“显示文档大纲”,然后从单元格向大纲的文件列表ViewController对象右键拖动即可。 - DawnSong
9个回答

43
如果你正在使用导航控制器,你需要将ViewController推入导航栈中。在这个例子中,我在我的Storyboard ID设置中将我的ViewController命名为"VDI"。

如果您使用导航控制器,需要将 ViewController 推送到导航堆栈中。在此示例中,我将我的 ViewController 命名为 "VDI",并在 Storyboard ID 设置中进行了配置。

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle: nil];
YourVC *dest = [storyboard instantiateViewControllerWithIdentifier:@"VDI"];
[self.navigationController pushViewController:dest animated:YES];

如果您不想让NavigationController将自己添加到"后退"历史记录中,您可以在添加之前从堆栈中弹出它,像这样:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle: nil];
YourVC *dest = [storyboard instantiateViewControllerWithIdentifier:@"VDI"];
UINavigationController *navController = self.navigationController;
[navController popViewControllerAnimated:NO];
[navController pushViewController:dest animated:YES];

这个和@TJ/@Jorge的方法都可以工作。我选择这种方式是因为它感觉更清晰。 另一种方法的好处是你可以在storyboard中看到你的循环segue,并且你可以在“prepareForSegue:”中处理所有的导航。 - siburb
1
完美运行!此外,对于那些想要重新创建此内容的人来说,这是在XCode中设置为“VDI”的“Storyboard ID”。 - Nerrolken

32
使用 Xcode 5,有一种更为简单的解决方案。
  1. 在Storyboard中点击表格单元格。
  2. 打开连接检查器(在右上方的向右箭头图标)。
  3. 在“触发的转换”下,您会看到“选择”。
  4. 从“选择”旁边的圆圈拖动到Storyboard中的单元格。

就这样。


2
这种方法不需要编写任何代码,非常有效。 - John Smith
2
这是针对Xcode 5+的正确答案,现在你应该使用“show”segue来实现它。 - CupawnTae
2
似乎对我无效,视图控制器没有变成“蓝色”,无法添加segue。 - db0

26

我开发了一种使用幻影按钮创建segue的方法。我相信它可以解决你的问题。你可以在我的回答这里阅读相关内容。


4
这让我找到了正确的方向。我在“Dock”上添加了一个按钮,并将其连接到文件列表视图控制器。现在我可以按照自己的意愿以编程方式执行转场了。谢谢! - Jorge
1
我希望不必这样做就能得到自我转换,但这可行。 - jogloran
2
Mustafa的解决方案不那么hacky,而且非常直接。使用虚拟按钮来制作到相同视图的转场只会让你的故事板变得混乱。 - strada

24

不必执行到相同的控制器,您可以从Storyboard中实例化一个视图控制器(相同的那个),然后将其推入导航控制器。


我更喜欢幽灵按钮的解决方案,因为我的所有前向转换都通过prepareForSegue:进行,而不是记住是在IB还是代码中创建的转换。 - Steve Moser

22

接口生成器方法:只需将segue连接到一个指向呈现视图控制器的故事板引用即可。


2
如果在IB中使用segue进行其他导航,则此方法是最好的!谢谢! - Roland T.
这个答案应该被接受,因为现在可以使用Storyboard引用(当OP提出问题时还不可用)。 - Christophe Blin
我发现这是最优雅的解决方案,现在它已经可用。 - ZShock
4
你需要为你的控制器赋予一个“Storyboard ID”,然后在引用中使用该ID作为“Referenced ID”字段。 - John J. Camilleri

18

正确的做法是使用故事板引用(Storyboard Reference),将其引用到要进行Segue的UIViewController本身,然后将Segue指向该UIViewController。

输入图像描述


12
在IOS 6中,相比使用虚拟按钮,有更简洁的解决方案。您仍然可以从表格单元格定义segue到视图控制器,并查看发送者以取消自动触发的segue:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    //storyboards should use segues and override prepareForSegue instead
    //but here we need custom logic to determine which segue to use
    id item = [self.fetchedResultsController objectAtIndexPath:indexPath];
    if (item meets condition) {
        [self performSegueWithIdentifier:@"segue1" sender:self];
    } else {
        [self performSegueWithIdentifier:@"segue2" sender:self];
    }
}

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    //ignore segue from cell since we we are calling manually in didSelectRowAtIndexPath
    return (sender == self);
}

4

以下是如何在不定义segue或硬编码其自身标识符的情况下推送当前视图控制器的另一个实例:

SameViewController *same = [self.storyboard instantiateViewControllerWithIdentifier: self.restorationIdentifier];
[self.navigationController pushViewController: same animated: YES];

您只需要将恢复标识符设置为与Storyboard ID相同(IB中有一个复选框可以实现此功能)。

Restoration ID


0
希望这可以帮到你。
我发现你可以创建多个原型单元格。
然后,你可以将每个单元格(在Storyboard中)链接到不同的视图。
就像这样:
NSString *CellIdentifier = @"Cell"; 
if (Condition2 ){
CellIdentifier = @"Cell2"; } 
if (Condition3 ){
CellIdentifier = @"Cell3"; }

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