单击单元格时 Segue 触发但不推送 / UITabBarController / UITableViewController

发布于 2024-12-25 13:03:38 字数 1994 浏览 2 评论 0原文

必须有一个简单的解决方案,但在浏览 StackExchange 4 小时后,我放弃并尝试在这里找到答案:

情况: iOS 5,Xcode 4.2.1,使用Storyboards

设置:

  • 根导航控制器= UITabBarController,包含5个项目
  • 每个选项卡链接到一个UITableViewController(通过segues),它完美地自动工作
  • 我为每个视图控制器和导航控制器(UITabBarController)提供了类
  • 我单击一个选项卡,说“程序”,它会向我显示一个项目列表(在链接的 UITableViewController 中),假设其中一个项目是“会话”,
  • 我单击“Sessions”,didSelectRowAtIndexPath 被调用得很好。
  • 我现在想执行一个segue(我已经从 UITableViewController (而不是单元格)连接到新的 UITableViewController 并给它一个标识符。
  • 我调用: [self PerformSegueWithIdentifier:@"programToSessions" sender:self];

  • prepareForSegue 被调用,但之后什么也没有。没有错误,没有警告。新的 UITableViewController 没有显示。

  • 注意:但是,如果我将segue切换到“模态”,它确实会出现 - 但它会丢弃/隐藏底部的原始选项卡栏(不是故意的......)

到目前为止,我的问题似乎有可能解决方案。导航控制器。我想,如果我在 AppDelegate 中设置导航控制器引用,则在加载实际根导航控制器(在 viewDidLoad 中)后启动/设置它,即基本上使用以下内容: app.navController = self.navigationController 在 vi​​ewDidLoad 中 - 这可以工作!正确的?因此,我将 segue 操作更改为: [app.navController PerformSegueWithIdentifier:@"programToSessions" sender:self];

然而,没有任何变化,它没有显示。

有什么想法吗?

已解决:

这里存在一些问题。主要问题是我错过了在 UITabBarController 和 UITableViewController 之间放置“导航控制器”。这可以通过向情节提要添加一个新的“导航控制器”,然后从 UITabBarController(rootViewController)拖动到这个新控制器并设置一个关系来完成。接下来,将 RELATIONSHIP 拖到 UITableViewController。因此,正如正确答案所概述的那样,它应该如下所示: UITabBarController --> (关系)--> UINavigationController——> (关系)--> UITableViewController

为了在最后一个 UITableViewController 之上加载新的 UITableViewController,一个简单的 segue 并通过代码调用它就足够了。最终的树将如下所示:

UITabBarController --> (关系)--> UINavigationController——> (关系)--> UITableViewController --> (继续)--> UITableViewController

给segue一个标识符。在代码中,使用:

     - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [self performSegueWithIdentifier:@"loadMyDetailView" sender:self];
    }

There must be a simple solution to this, but after 4 hours of browsing StackExchange, I'm giving up and trying to get this answered here:

Situation:
iOS 5, Xcode 4.2.1, using Storyboards

Setup:

  • Root Navigation Controller = UITabBarController with 5 items
  • Each tab links to a UITableViewController (via segues), which works perfectly, automatically
  • I have classes for each view controller and the navigation controller (UITabBarController)
  • I click on a tab, say "Program", and it shows me a list of items (in the linked UITableViewController), say one of these items is "Sessions"
  • I click on "Sessions", didSelectRowAtIndexPath gets called just fine.
  • I want to perform a segue now (which I have connected from that UITableViewController, not the cell, to the new UITableViewController and given it an identifier.
  • I call:
    [self performSegueWithIdentifier:@"programToSessions" sender:self];

  • prepareForSegue gets called, but nothing afterwards. No error, no warning. The new UITableViewController doesn't show up.

  • Note: It DOES show up, however, if I switch the segue to a "modal" - but it discards/hides the original tab bar at the bottom then (not intended...)

So far, my problem seemed to have a likely solution. The navigation controller. I figured, if I setup a navigation controller reference in the AppDelegate, initiated/set it once the actual root navigation controller is loaded (in viewDidLoad), i.e. basically used something along the lines of: app.navController = self.navigationController in the viewDidLoad - this could work! Right? So, I changed the segue action to:
[app.navController performSegueWithIdentifier:@"programToSessions" sender:self];

Yet, nothing changes, it does not show up.

Any ideas?

Solved:

There were a few issues here. Major issue was the fact that I missed putting a "Navigation Controller" between the UITabBarController and the UITableViewController. This can be done by adding a new "Navigation Controller" to the storyboard, then drag from UITabBarController (the rootViewController) to this new controller and set a RELATIONSHIP. Next, drag a RELATIONSHIP to the UITableViewController. So, as outlined by the correct answer it should look like:
UITabBarController --> (relationship) --> UINavigationController --> (relationship) --> UITableViewController

In order to load new UITableViewControllers on top of the last UITableViewController, a simple segue and calling it through code will suffice. The final tree will look like:

UITabBarController --> (relationship) --> UINavigationController --> (relationship) --> UITableViewController --> (segue) --> UITableViewController

Give the segue an identifier. In code, use this:

     - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [self performSegueWithIdentifier:@"loadMyDetailView" sender:self];
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无畏 2025-01-01 13:03:38

您必须使用 prepareForSegue:sender: 来触发 didSelectRowAtIndexPath: 的等效项。 (清空后者。)segue 没有将新的视图控制器推送到导航堆栈上,而是已经有了一个可以自动工作的属性 destinationViewController。如果您想自定义新的视图控制器,可以修改此属性。确保segue.identifier正确!

另外,从你的问题中我注意到视图控制器的控制器有些混乱。您提到其中两个:选项卡栏控制器和导航控制器。在故事板中,设置应该是这样的:

TabBarController --(relationship)--> NavigationController 
--(relationship)--> ViewController 
--(segue)--> next ViewController

确保故事板中的所有这些都是正确的,然后看看它是否有效。

You have to use prepareForSegue:sender: to fire the equivalent of didSelectRowAtIndexPath:. (Empty out the latter.) Instead of pushing the new view controller on the navigation stack, the segue already has a property destinationViewController that will just work automatically. You can modify this property if you want to customize the new view controller. Make sure segue.identifier is correct!

Also, from your question I notice some confusion about the controllers of view controllers. You mention two of these: the tab bar controller and a navigation controller. In storyboard, the setup should be like this:

TabBarController --(relationship)--> NavigationController 
--(relationship)--> ViewController 
--(segue)--> next ViewController

Make sure all these are correct in storyboard and see if it works.

江城子 2025-01-01 13:03:38

您不必以编程方式performSegue
您可以通过控制从第一个 UITableViewController 的 UITableViewCell 拖动到第二个 UITableViewController 来创建从故事板上的第一个 UITableViewController 到第二个 UITableViewController 的 Segue。如果不执行segue,最有可能的原因是方法中的单元格标识符

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

与“属性检查器”中的单元格标识符不匹配。

要将数据从第一个 UITableViewController 传递到第二个,请将以下方法添加到第一个:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"loadMyDetailView"]) {
        MyDetailViewController *detailVC = [segue destinationViewController];
        NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
        detailVC.dataToPass = [self getDataToPass:selectedRowIndex.row];
    }

}

You don't have to performSegue programmatically.
You could create a segue from the first UITableViewController to the second on the storyboard, by control dragging from the UITableViewCell of the first UITableViewController to the second UITableViewController. If the segue is not performed, its most likely reason is that, cell identifier in the method

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

and in the "Attributes Inspector" do not match.

To pass data from the the first UITableViewController to the second add the following method to the first:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"loadMyDetailView"]) {
        MyDetailViewController *detailVC = [segue destinationViewController];
        NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
        detailVC.dataToPass = [self getDataToPass:selectedRowIndex.row];
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文