我正在开发我的第一个应用程序。这是我想要完成的:
将会有一个带有几个不同选项的菜单。为简单起见,假设这是由带有IBAction outlets的UIButtons组成的,并且存在随时弹出菜单的功能。
按下每个菜单按钮时,应显示不同的导航控制器的内容。如果用户调出菜单并做出不同的选择,应该不会影响他当前正在操作的导航控制器;新选择的导航链显示在旧的导航链之上,并且通过该菜单,用户可以随时返回到他在上一个导航链上离开的视图。
可视化插图(单击以获得更高的分辨率):
请注意,有3个不同的导航控制器/链。根视图控制器(这也是这个简化版本中的菜单)不是它们的一部分。如果用户位于选项2的屏幕3上,然后从菜单中选择选项1,然后从菜单中选择选项2,然后(再次)从菜单中选择选项2,那么他应该看着选项2的屏幕3--就在他离开的地方;当他之前离开导航链时,他正在查看的视图控制器应该回到顶部。
如果没有导航控制器,我可以让一个按钮实例化,并从情节提要中显示一个视图控制器:
- (IBAction)buttonPressed:(id)sender {
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"View 2"];
[self presentViewController:controller animated:YES completion:nil];
}
但是,我不知道如何让这两种方法在涉及导航控制器的情况下工作。此外,我不确定这两种方法是不是正确的选择,因为我并不总是希望实例化一个新的视图控制器:当按下菜单按钮时,应该执行检查以查看视图(导航?)具有相应标识符的控制器已被实例化。如果是这样的话,应该简单地将其设置为顶部视图控制器。
总而言之,以下是我的问题:
1)我应该如何实例化和显示嵌入到导航控制器中的视图控制器,最好使用故事板ID?是否使用导航控制器或视图控制器的情节提要ID?
2)如何检查实例是否已经存在?同样,我应该检查现有的导航控制器还是视图控制器,最好的方法是什么?
3)如果选定的导航链已经被实例化,并且在某个视图控制器堆栈中,那么将其放在顶部的最佳方法是什么?
谢谢你!!
附注--如果知道如何粘贴代码片段并保留缩进和颜色格式,那就更好了:)
发布于 2013-05-12 08:07:03
正如Rob所建议的,选项卡栏控制器将为您的设计提供良好的组织原则。
在你的故事板中添加一个UITabBarController,给它一个故事板iD。将三组viewControllers (及其各自的navController)中的每一组都分配给tabBarController中的一个选项卡项。
UITabBarController
|--> UINavigationController --> VC1 ---> VC2 -->
|--> UINavigationController --> VC1 ---> VC2 -->
|--> UINavigationController --> VC1 ---> VC2 -->
在你的应用委托中,创建一个强大的属性来保持标签栏控制器的指针。因为标签栏控制器保持指向它的所有标签项的指针,所以这将照顾到你的每一组viewControllers的状态。您不必为它们中的任何一个保留单独的指针,您可以通过tabBarController的viewControllers
属性获取对它们的引用。
@property (strong, nonatomic) UITabBarController* tabVC;
在启动时初始化它
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard storyBoard =
[UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
self.tabVC = [storyBoard instantiateViewControllerWithIdentifier:@"tabVC"];
//hide the tab bar
for (UINavigationController* navController in self.tabVC.viewControllers)
[navController.viewControllers[0] setHidesBottomBarWhenPushed:YES];
return YES;
}
隐藏选项卡栏的另一种方法是选中每个(初始) viewControllers的属性检查器中的“推入时隐藏底部栏”框。您不必为后续的viewControllers执行此操作,只需在该选项卡项中看到的第一个就可以了。
然后,当您需要导航到某个navController组时,…
- (IBAction)openTab:(UIButton*)sender {
AppDelegate* appDelegate =
(AppDelegate*)[[UIApplication sharedApplication] delegate];
if ([sender.titleLabel.text isEqualToString: @"Option 1"]) {
appDelegate.tabVC.selectedIndex = 0;
}else if ([sender.titleLabel.text isEqualToString: @"Option 2"]){
appDelegate.tabVC.selectedIndex = 1;
}else if ([sender.titleLabel.text isEqualToString: @"Option 3"]){
appDelegate.tabVC.selectedIndex = 2;
}
[self presentViewController:appDelegate.tabVC
animated:YES completion:nil];
}
(本例使用presentViewController
,您的应用程序设计可以通过其他方式使用…)
更新
如果您希望在不使用选项卡栏控制器的情况下执行此操作,则可以实例化一个包含指向每个导航控制器的指针的数组:
UINavigationController* ncA =
[storyboard instantiateViewControllerWithIdentifier:@"NCA"];
UINavigationController* ncB =
[storyboard instantiateViewControllerWithIdentifier:@"NCB"];
UINavigationController* ncC =
[storyboard instantiateViewControllerWithIdentifier:@"NCC"];
self.ncArray = @[ncA,ncB,ncC];
这样做的好处是没有选项卡栏来隐藏…
则您的选择看起来像…
- (IBAction)openNav:(UIButton*)sender {
AppDelegate* appDelegate =
(AppDelegate*)[[UIApplication sharedApplication] delegate];
int idx = 0;
if ([sender.titleLabel.text isEqualToString: @"option 1"]) {
idx = 0;
}else if ([sender.titleLabel.text isEqualToString: @"option 2"]){
idx = 1;
}else if ([sender.titleLabel.text isEqualToString: @"option 3"]){
idx = 2;
}
[self presentViewController:appDelegate.ncArray[idx]
animated:YES completion:nil];
}
发布于 2013-05-12 04:38:42
1 /您可以在主viewController的viewDidLoad方法中实例化viewController,因此它只实例化一次。
现在,如果你想要显示你的控制器,你最好按下它:
- (IBAction)buttonPressed:(id)sender {
// Declare your controller in your .h file and do :
controller = [self.storyboard instantiateViewControllerWithIdentifier:@"View 2"];
// Note you can move this line in the viewDidLoad method to be called only 1 time
// Then do not use :
// [self presentViewController:controller animated:YES completion:nil];
// Better to use :
[self.navigationController pushViewController:controller animated:YES];
}
2 /我不确定,但如果您想检查实例是否已经存在,只需检查:
if (controller) {
// Some stuff here
} // I think this checks if controller is initiated.
3 /我知道这不是一个好建议,但我要告诉你不用担心检查你的控制器是否已经存在,因为我认为再次使用这两行可以更容易地访问你的viewController:
controller = [self.storyboard instantiateViewControllerWithIdentifier:@"View 2"];
[self.navigationController pushViewController:controller animated:YES];
4 /由于特定的样式表,我不确定是否可以在这里使用颜色。
我不确定你的问题是否真的有很好的答案,但我希望这会对你有所帮助。
https://stackoverflow.com/questions/16501270
复制相似问题