使用另一个UINavigationController推送View Controller

时间:2013-07-04 16:15:07

标签: ios objective-c cocoa-touch ios5 ios6

这就是我的应用程序的样子。我已经将UINavigationController子类化了,当你点击类似于导航栏的按钮时,MenuViewController会滑出。如何从UITableViewController菜单中的didSelectRow将我的VC1,VC2,VC3之一推送到ContentViewController?

                -> SlidingViewController
                 /                   \
            Container             Container       
                |                     |
        MenuViewController    ContentViewController
                |                      |
     UITableViewController   SubClassed UINavigationController
                                  |    |    |    |
                                 VC1  VC2  VC3  VC4

通常我会做类似下一个代码的事情但是上面的情况我不知道如果我不在同一个UINavigationController中我怎么能推新的视图控制器。

NSString * storyboardName = @"MainStoryboard_iPhone";
NSString * viewControllerID = @"ViewID";
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
MyViewController * controller = (MyViewController *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
[? presentViewController:controller animated:YES completion:nil];

修改:

可行的解决方案有效,但我不确定这是否是一个很好的方法。我使用单例来保存我的导航控制器并在以后使用它。

在我的ContentViewController中:

[DataManager sharedDataManager].navController = self.navigationController;

在MenuViewController中的didSelectRow中:

[[DataManager sharedDataManager].navController presentViewController:controller animated:YES completion:nil];

3 个答案:

答案 0 :(得分:4)

您不希望MenuViewController了解视图控制器层次结构中除自身及其子项之外的任何内容。您有两个选项可以实现这种良好的设计。

1。使用委托

首先,您希望拥有一个MenuViewControllerDelegate,例如menuViewController:didSelectOption:。当菜单中发生某些事情时,MenuViewController将向其委托对象发送适当的委托消息。

现在要监听该委托消息,您将需要一个符合NSObject的控制器对象(可以是视图控制器或只是常规MenuViewControllerDelegate)并设置{{1}的委托对自己。然后,该控制器对象将处理MenuViewController可能发送的任何委托消息,例如选择菜单选项时,将新视图控制器推送到MenuViewController

2。发布通知

这两者中更脆弱。如果您的视图控制器层次结构中有很多需要知道菜单中发生某些事情的事情,您可以使用通知。

所以ContentViewController会发布一个通知,可能名为MenuViewController,然后任何已注册该通知的感兴趣的接收者都会收到通知并做他们的事情。

答案 1 :(得分:2)

在你的App Delegate中(或者为了响应你的编辑,任何持久的单例都可以,是的),创建属性来保存你的View Controller实例。

@property (nonatomic, strong) MenuViewController *menuViewController;

...等等所有你的vc。

每当您稍后初始化它们时,请在App委托上设置此属性以保存VC。

MenuViewController *menuVC = [[MenuViewController alloc] init];

AppDelegate *appDel = [[UIApplication sharedApplication] delegate];
appDel.menuViewController = menuVC;

现在,只要您需要提供此实例,就可以获得此实例。您还可以在menuViewController上设置要保留在内存中的任何属性。

注意:要意识到自己是个好记忆的公民。编写didReceiveMemoryWarning方法,以便在VC再次可见时释放您可以轻松重新加载的任何内容,这样您就不会让应用程序在内存中同时保留太多内容。

答案 2 :(得分:1)

你应该有一个类(可能是app delegate)来创建你的容器结构。它可以访问创建的视图控制器。您的表视图控制器和导航控制器最初可能不存在,但最初创建所有内容的类应该通过将导航控制器或内容视图控制器的引用传递给表视图控制器或菜单视图来“构建结构之间的桥梁”控制器。该引用应存储在属性中,并允许您干净地呈现视图控制器。

此类设置优于浏览parentViewController或类似链接,因为这会导致以非透明方式将您绑定到特定结构。


或者,在故事板中,您只需添加IBOutlet属性并直接在那里建立连接(如果在加载故事板时预先创建了所有视图控制器)。