我的UIViewController
包含另外两个UIViewControllers
作为属性。
MenuViewController包含:
@property (nonatomic, strong) TeamsViewController *teamsViewController;
@property (nonatomic, strong) ResultsViewController *resultsViewController;
MenuViewController包含表格视图,当用户点击单元格“show teams”时,我需要初始化teamsViewController并显示teamsViewController视图。当用户按下单元格“显示结果”时,同样的事情,但在这种情况下,我需要显示resultsViewController视图。
所以,我通常这样做是以单向方式在按下单元格时初始化控制器并调用addSubview方法来添加控制器视图。但我认为这不是一个好的解决方案我是对的吗?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_teamsViewController) _teamsViewController = nil;
_teamsViewController = [TeamsViewController new]
[self.view addSubView:_teamsViewController];
}
上面的方法可以吗?
我的视图层次结构中的每一个都由它自己的控制器管理。所以由MenuViewController管理的白色和由ResultViewController管理的灰色视图和由TeamsViewController管理的蓝色视图。
正如我之前所说,当我点击菜单视图控制器中的相应单元格时,我需要显示团队或结果。但是每个视图都有另一个视图控制器。或许我对视图控制器范式感到困惑?也许TeamsViewController应该是TeamsView,ResultsViewController应该是ResultsView?因此,两个视图控制器都具有在其控制器中管理的表。所以我不认为它必须是UIView而不是UIViewController。
答案 0 :(得分:1)
我建议使用故事板并确保拥有"故事板ID"对于他们每个人。这样,根据需要推送各种UIViewController
实例变得更容易一些。这是我的典型模式:
UIViewController *vc = [self.storyboard
instantiateViewControllerWithIdentifier:@"selected identifier"];
[self.navigationController pushViewController:vc animated:YES];
此外,除非您需要在子视图控制器中设置属性,否则无需对其进行属性引用。此外,此答案假定您使用UINavigationController
,并将MenuViewController
设置为rootViewController
。您可以使用Storyboard(简单且可能是首选方式)在IB中进行设置,或者使用以下代码进行设置:
MenuViewController *vc = [[UIViewController alloc] initWithNibName:@""
bundle:nil];
UINavigationController *navVc = [[UINavigationController alloc]
initWithRootViewController:vc];
答案 1 :(得分:1)
我认为最好的办法是将其设置为UINavigationController。 UINavigationController继承自UIViewController,因此您不会以这种方式丢失任何功能。然后你可以像这样设置它:
//MenuViewController.h
@interface MenuViewController : UINavigationController
@property (nonatomic, strong) TeamsViewController *teamsViewController;
@property (nonatomic, strong) ResultsViewController *resultsViewController;
//Insert other properties and methods....
@end
并且在有人点击某个单元格时调用的方法中,您只需执行此操作:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.teamsViewController) {
self.teamsViewController = [[UIViewController alloc] initWithNibName:@"nibName" bundle:nil];
}
[self pushViewController:self.teamsViewController animated:YES];
}
现在,你有两个视图控制器,所以你必须告诉你的方法上面哪一个推入堆栈。如果行是固定的,您可以根据indexPath
简单地决定显示哪一行,但如果它更动态(即从数据库创建tableview),那么您需要在这里使用一些更复杂的逻辑代码。 / p>
没有做太多的假设,但为了给你一些一般的指导,当你创建一个单元格时,你通常会在它上面设置某种标志来指示它是什么类型。如果您只有两个状态,可以使用NS_ENUM或简单的BOOL来完成(我更喜欢尽可能使用ENUM,因为它们更具描述性)。然后,您将在tableView:didSelectRowAtIndexPath:
方法中检查该标志是否存在,将相应的视图推送到导航堆栈。这样的事情(这不是文字代码,但只是为了给你一个想法:
// 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;
}
}
您仍然需要在团队或结果视图控制器中进行初始化以显示视图,但这应该引导您向大方向发展。