简体   繁体   English

在父视图控制器中管理几个UIViewControllers

[英]Manage few UIViewControllers in parent view controller

I have UIViewController that contain another two UIViewControllers as properties. 我有UIViewController包含另外两个UIViewControllers作为属性。

MenuViewController contains: MenuViewController包含:

@property (nonatomic, strong) TeamsViewController *teamsViewController; 
@property (nonatomic, strong) ResultsViewController *resultsViewController;

The MenuViewController contains table view and when user tap on the cell "show teams" I need to initialize teamsViewController and show teamsViewController view. MenuViewController包含表视图,当用户点击单元格“show teams”时,我需要初始化teamsViewController并显示teamsViewController视图。 The same thing when user press on the cell "show results" but in this case I need to show resultsViewController view. 当用户按下单元格“显示结果”时,同样的事情,但在这种情况下,我需要显示resultsViewController视图。

So, I usually do this is in one way initialize controllers when cell is pressed and call addSubview method that will add controllers view. 因此,我通常这样做是以一种方式在按下单元格时初始化控制器并调用addSubview方法来添加控制器视图。 But I think it is not good solution am I right? 但我认为这不是一个好的解决方案我是对的吗?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (_teamsViewController) _teamsViewController = nil;
    _teamsViewController = [TeamsViewController new]
    [self.view addSubView:_teamsViewController];

}

Is the method above ok? 上面的方法可以吗?

There is my hierarchy of view each of them managed by its own controller. 我的视图层次结构中的每一个都由它自己的控制器管理。 So the white you managed by MenuViewController and the gray view managed by ResultViewController and blue view managed by TeamsViewController. 因此,由MenuViewController管理的白色和由ResultViewController管理的灰色视图和由TeamsViewController管理的蓝色视图。

As I said before when I tap on appropriate cell in menu view controller I need to show teams or results. 正如我之前所说,当我点击菜单视图控制器中的相应单元格时,我需要显示团队或结果。 But each of this view has another view controller. 但是每个视图都有另一个视图控制器。 Or maybe I confused about view controller paradigm? 或许我对视图控制器范式感到困惑? Maybe TeamsViewController should be a TeamsView and ResultsViewController should be ResultsView ? 也许TeamsViewController应该是TeamsView,ResultsViewController应该是ResultsView? So both view controllers has the table as well that managed in their controllers. 因此,两个视图控制器都具有在其控制器中管理的表。 So i don't think it has to be a UIView instead of UIViewController. 所以我不认为它必须是UIView而不是UIViewController。

在此输入图像描述

I'd recommend using Storyboards and making sure to have a "Storyboard ID" for each of them. 我建议使用Storyboards并确保每个都有一个“Storyboard ID”。 That way, it becomes a bit easier to push various UIViewController instances, as needed. 这样,根据需要推送各种UIViewController实例变得更容易一些。 This is my typical pattern: 这是我的典型模式:

UIViewController *vc = [self.storyboard
    instantiateViewControllerWithIdentifier:@"selected identifier"];
[self.navigationController pushViewController:vc animated:YES];

Also, unless you need to set properties in the child view controller, there's no need to have a property reference to it. 此外,除非您需要在子视图控制器中设置属性,否则无需对其进行属性引用。 Further, this answer assumes that you're using a UINavigationController , with your MenuViewController set as the rootViewController . 此外,这个答案假定您正在使用UINavigationController ,并将MenuViewController设置为rootViewController You can either set this up in IB with a Storyboard (easy and probably the preferred way), or in code like this: 您可以使用Storyboard(简单且可能是首选方式)在IB中设置它,或者使用以下代码:

MenuViewController *vc = [[UIViewController alloc] initWithNibName:@"" 
                                                            bundle:nil];
UINavigationController *navVc = [[UINavigationController alloc]
                                  initWithRootViewController:vc];

I think your best bet is to set this up as a UINavigationController. 我认为你最好的选择是将其设置为UINavigationController。 UINavigationController inherits from UIViewController so you aren't losing any functionality this way. UINavigationController继承自UIViewController,因此您不会以这种方式丢失任何功能。 You could then set it up like this: 然后你可以像这样设置它:

//MenuViewController.h
@interface MenuViewController : UINavigationController
   @property (nonatomic, strong) TeamsViewController *teamsViewController; 
   @property (nonatomic, strong) ResultsViewController *resultsViewController;
   //Insert other properties and methods....

@end

and in the method called when someone clicks on a cell, you would simply do this: 并且在有人点击某个单元格时调用的方法中,您只需执行以下操作:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (!self.teamsViewController) {
       self.teamsViewController = [[UIViewController alloc] initWithNibName:@"nibName" bundle:nil];
    }
    [self pushViewController:self.teamsViewController animated:YES];
}

Now, you have two view controllers, so you have to tell your method above which one to push onto the stack. 现在,你有两个视图控制器,所以你必须告诉你的方法上面哪一个推入堆栈。 If the rows are fixed, you can simply decide which one to show based on indexPath but if it's more dynamic (ie tableview is created from a database) then you'll need to have some more complex logic code here. 如果行是固定的,您可以简单地决定基于indexPath显示indexPath但如果它更动态(即tableview是从数据库创建的)那么您需要在这里有一些更复杂的逻辑代码。

Without making too many assumptions, but to give you some general guidance, when you create a cell you would generally set some sort of flag on it to indicate what type it is. 在没有做太多假设的情况下,但是为了给你一些一般的指导,当你创建一个单元格时,你通常会在它上面设置某种标志来指示它是什么类型。 This can be done with an NS_ENUM or with a simple BOOL if you only have two states (I prefer to use ENUMs whenever possible as they are much more descriptive). 如果您只有两个状态,可以使用NS_ENUM或简单的BOOL来完成(我更喜欢尽可能使用ENUM,因为它们更具描述性)。 You would then check for the existence of that flag in the tableView:didSelectRowAtIndexPath: method, pushing the corresponding view onto the navigation stack. 然后,您将在tableView:didSelectRowAtIndexPath:方法中检查该标志是否存在,将相应的视图推送到导航堆栈。 Something like this (this is not literal code, but shown just to give you an idea: 像这样的东西(这不是文字代码,但只是为了给你一个想法:

// This code assumes in the method tableView:cellForRowAtIndexPath:
// you have set the tag property to '1' if a TeamsViewController is
// needed or '2' if a ResultsViewController is needed when that cell
// is pressed.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        self.teamsViewController = self.teamsViewController ? self.teamsViewController : [[UIViewController alloc] initWithNibName:@"TeamsViewController" bundle:nil];
        self.resultsViewController = self.resultsViewController ? self.resultsViewController : [[UIViewController alloc] initWithNibName:@"ResultsViewController" bundle:nil];
        switch ([[tableView cellForRowAtIndexPath:indexPath] tag]) {
           case 1:
              [self pushViewController:self.teamsViewController animated:YES];
              break;
           case 2:
              [self pushViewController:self.resultsViewController animated:YES];
              break;
           default:
              break;
        }
    }

You would still need to do your initialization in your teams or results view controller to show the view but this should steer you in the general direction. 您仍然需要在团队或结果视图控制器中进行初始化以显示视图,但这应该引导您向大致方向发展。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM