如何以编程方式为情节提要中的子视图设置视图控制器?

Posted

技术标签:

【中文标题】如何以编程方式为情节提要中的子视图设置视图控制器?【英文标题】:how to set view controller programmatically for subview in storyboard? 【发布时间】:2012-07-08 15:02:57 【问题描述】:

(在故事板中设计,截图如下)我的 rootviewcontroller 视图上有两个子视图

在我的代码中,我想为每个子视图分配一个 单独的 视图控制器。即为 TableView 分配一个 tableViewController。

我尝试在 awakeFromNib(或 ViewDidLoad)方法中执行此操作,但无济于事。我的 tableview 控制器中的委托方法永远不会被调用。我认为即使在我分配的 tableviewcontroller 可以做某事之前,storyboard 也可以在这里加载子视图。

self.myTableViewController = (TodoListViewController *)[[UITableViewController alloc]  initWithStyle:UITableViewStylePlain];
self.myTableView.delegate = self.myTableViewController;
self.myTableView.dataSource = self.myTableViewController;
self.myTableViewController.tableView = self.myTableView;

我不确定在情节提要中有这样的视图时是否允许这样做,或者我做错了什么?

【问题讨论】:

【参考方案1】:

我来到这个网站是因为我遇到了类似的问题。实际上我正在做同样的事情:我有一个带有两个子视图的视图控制器(全部在一个有很多约束的情节提要中定义)。

在 viewDidLoad 的 containerviewcontroller 中,我正在执行与您相同的调用(但我首先定义了视图):

self.myTableViewController = (TodoListViewController *)[[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
self.myTableViewController.tableView = self.myTableView;
self.myTableView.delegate = self.myTableViewController;
self.myTableView.dataSource = self.myTableViewController;

这对我有用(我想,这是你的问题:你周围没有导航控制器......并确保你的 tableview 的出口在情节提要中真正连接。)。

但真正的问题出现在正确的接线之后。如果你进入一个单元格,你可能想给 nextView 一些 cellID。由于您手动定义了 tableviewcontroller,只有您的委托方法 didSelectRowAtIndexPath 被调用,而不是 prepareForSegue。

我玩过从情节提要中实例化视图控制器

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"aStoryboard" bundle:nil];
self.myTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"myTableViewID"];

但是 segue 没有被调用。直接调用它(performSegueWithIdentifier:...)不起作用,因为这个 tableviewcontroller 不是由导航控制器管理的。

对我来说,最终在 containerViewController 中调用了 prepareForSegue 方法,该方法可以将调用委托给它的子视图控制器。

编辑:实际上真正的解决方案是不要。有一个“容器视图”对象可以添加到视图中,并定义视图控制器的区域,该区域可以包含子视图控制器。这是我真正想做的。

【讨论】:

+1 表示“容器视图”部分。正是我正在寻找的。谢谢。【参考方案2】:

使用您的 viewDidLoad 方法再试一次,这是最简单的答案。如果方法没有加载,您可能需要查看方法中的其他内容,因为如果应用程序很大,因为他们经常使用故事板,您可能会有冲突的方法。

我也会看看这个: http://blog.waynehartman.com/archive/2012/01/07/uistoryboard-on-ios-5-the-good-the-bad-and-the.aspx

它显示了人们在以编程方式使用任何故事板功能时最常见的事故

希望对您有所帮助!

【讨论】:

好点,但该应用程序目前非常简单,并且正如您所指出的那样,没有很多代码可以重叠。因此,在 ViewDidLoad 中再次尝试目前没有太大帮助。【参考方案3】:

听起来您想为自己编写一个自定义容器控制器,例如类似于 UISplitViewController。这是苹果在UIViewController class reference 中关于这样做的简短文档。例如,您可以在容器控制器的 viewDidLoad:viewWillAppear: 方法中以编程方式实例化子控制器。不过,我认为您不能让 IB 为您实例化孩子,就像您可以连接标签栏或导航控制器与其孩子的关系一样。 (如果有办法,我想知道!)

【讨论】:

【参考方案4】:

在情节提要中设置类和委托通常是最简单的(如包括this one 在内的众多教程中所示)。

如果您真的想将滚动视图和表格视图放入同一个视图中,那么您需要查看UIViewController instantiateViewControllerWithIdentifier:,您可以合理轻松地拉出多个视图控制器(最好使用它们的适当类、委托和故事板中设置的源),并将它们的视图添加到您的外包装视图中。我会说我已经做到了这一点,你可以用它相当容易地做一些很酷的事情,但它通常不是最干净的做事方式。

【讨论】:

感谢您的评论。但是 instantiateViewControllerWithIdentifier 在这里没有帮助,因为表视图的视图控制器不在故事板上。它不允许我将 viewcontroller 分配给子视图,正如我所知(tableview 是这里的子视图),因此是关于 SO 的问题。 为什么不在情节提要上呢?故事板使将事物连接在一起变得容易。出于控制的原因,我一直希望在代码中做很多事情,所以我理解这是否是你的动机,但如果你要使用故事板,那么完全使用它会更容易。 故事板是否允许为子视图点赞视图控制器?如果是的话,你能指点我正确的目录吗?根据我的经验,它不允许为子视图设置视图控制器。 可能还有其他方法可以做到这一点,但对于您的示例来说,一种方法是,您有一个外部视图和两个内部视图,每个内部视图都有自己的控制器,那就是拥有 3 个视图控制器在你的故事板上。每个子视图一个,与每个子视图完全连接。一个用于外部视图。外部视图的控制器将在其 viewDidLoad 中为每个子视图控制器调用 instantiateViewControllerWithIdentifier,然后将它们的视图放置在它想要的位置。它确实为您的故事板添加了更多“混乱”,但每一部分都可以非常简单。 1) 当您说“完全连接”时 - 这里的问题是情节提要不允许将 vc 连接到子视图。 (2) 如帖子中所述,我已经尝试在 viewDidLoad 中进行设置,但是到那时子视图已经加载并且完全忽略了 viewDidLoad 方法中任何分配的 vc。

以上是关于如何以编程方式为情节提要中的子视图设置视图控制器?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式设置 rootViewController 不起作用,仅在 Xcode 11 中从情节提要中选择初始视图控制器

如何以编程方式从情节提要中填充静态 UITableView?

如何在没有情节提要的情况下以编程方式实例化视图控制器

如何以编程方式创建带有约束的视图

如何以编程方式快速使用情节提要 ID 获取当前视图控制器(当前正在呈现)?

如何在 ios swift 中以编程方式将情节提要视图控制器加载到标签栏控制器中?