实例化具有特定标识符的视图控制器并传递数据

7

我正在使用Storyboard开发我的应用程序,并且想要从一个视图传递数据到另一个视图。

我没有使用segues,而是使用instantiateViewControllerWithIdentifier。在这种情况下,我从我的第一个TableViewController实例化到一个NavigationController,因为我需要第二个TableViewController中的导航。现在我想根据点击的行来从我的第一个TableviewController传递数据到我的第二个TableviewController。在这种情况下, newTopViewController将是我的NavigationController,但我的问题是如何将数据从firstTableViewController传递到secondTableviewController

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSString *identifier = [NSString stringWithFormat:@"%@Top", [menuArray objectAtIndex:indexPath.row]];


        UIViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];




    }

enter image description here


可能是在视图控制器之间传递数据的重复问题。 - Carl Veazey
如果实例化的控制器是导航控制器,我该如何传递数据? - halloway4b
听起来你的问题是这样的:“我正在使用instantiateViewControllerWithIdentifier:从Storyboard中加载一个UINavigationController。在导航控制器内部有一个表视图控制器。请注意,我没有使用segue,如何将数据传递给表视图控制器并显示导航控制器?” 是这样吗? - Carl Veazey
没错。因为如果我直接展示表视图控制器,就没有导航栏了。我会添加一张屏幕截图。 - halloway4b
所以我将从菜单视图控制器传递数据到示例表视图控制器,但要实例化导航控制器,否则我将没有导航栏。 - halloway4b
显示剩余2条评论
4个回答

17
如果您实例化一个 navigationController,您可以使用 viewControllers 属性来获取导航控制器中的内部视图控制器。 类似于这样的代码:
UINavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
MBFancyViewController *viewController = navigationController.viewControllers[0];

// setup "inner" view controller
viewController.foo = bar;

[self presentViewController:navigationController animated:YES completion:nil];

你做得很好。非常感谢。有了这个提示,我发现UINavigationController有一个叫做topViewController的属性。非常感谢。两种方式都能完美运行。我已经用另一种方式编辑了你的答案。 - halloway4b

5
newTopViewController.anyVariableToShow= anyVariableToSend;

我经常在我的几个应用程序中这样做...

//创建新的VC(视图控制器)

CookViewController *detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"CookVC"];

//Set recipe
[detailViewController setRecipe:recipe];

//Pop over VC (can be pushed with a nav controller)
[self  presentPopupViewController:detailViewController animationType:MJPopupViewAnimationFade];

如果您没有使用导航控制器或转场,那么我认为您需要重新考虑您的应用设计。

newTopViewController是一个NavigationController,但我想将数据传递到我的secondTableViewController。 - halloway4b
如果我说newTopViewController.title = @"Whatever";,标题不会改变,因为secondTableviewController是在导航栏下显示的。如果我直接实例化secondTableViewController,我可以像secondTableViewController.title = @"Whatever"这样传递数据,但是我的tableview中没有导航栏。 - halloway4b

0
实际上这不仅仅是一个数据传递的问题,而是一个程序控制和数据传输的问题。 即使您想使用故事板而没有故事板的含义,您也需要重新考虑您应用的概念,这取决于您,我希望您有充分的理由来做您所做的事情。
因此,当您决定不使用segue时,您失去了一种新的舒适的方式来实例化一个新的控制器并传输数据,您必须将控制和数据的传输分为两个不同的步骤。当您在故事板中实例化另一个场景(就像您使用instantiateViewControllerWithIdentifier:一样)时,您只是实例化了一个新的控制器并传输了控制权,但没有传输数据。只需将其视为以旧方式从xib实例化新控制器(因此您必须在第二个视图控制器中使用initWithCoder:或awakeFromNib,因为故事板不会调用initWithName:bundle:),但没有做更多的事情。
因此,您将拥有一个新的控制器(它在第二个故事板的标识部分中命名),它悬挂在宇宙中,与任何其他东西都没有关系或连接(正如故事板图片很好地说明了这一点),您可以随心所欲地使用它。

所以你想做一些事情,需要从前一个故事板(ViewController)获取数据。你需要的是将这些数据提供给第二个故事板(ViewController),正如你所知道的,在故事板出现之前就有很多解决方案可用。

关于你的代码,“数据传输”取决于你的设计,无论这两个控制器是否彼此的子类等等...

如果你不想处理子类化,并尽可能地解耦它们,最好的方法就是在第一个控制器中创建一个数据属性,并从第二个控制器中引用它们(在导入第一个的.h文件后),并在其viewDidLoad或initWithCoder:或任何需要它们的地方引用它们,如下:

secondViewControllerdata = firstViewControllerdata.thatDataProperty

当然,您也可以反过来做同样的事情,将第二个控制器的属性设置为公共属性,并在第一个视图控制器中引用它。


0

在UIViewController中,您可以定义一些参数来接收数据:

@property (assign) int param1;

@property (retain) NSMutableArray *param2;

并使用以下代码传递数据:

[newTopViewController setParam1:XX];

[newTopViewController setParam2:XX];


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