我正在开发我的第一个应用程序.这是我想要完成的:
I'm working on my first app. Here's what I want to accomplish:
会有一个包含几个不同选项的菜单.为简单起见,假设它由带有 IBAction 插座的 UIButtons 组成,并且存在随时拉出菜单的功能.
There will be a menu with several different options. For simplicity, assume this is comprised of UIButtons with IBAction outlets and the functionality exists to pull up the menu at any time.
每个菜单按钮在按下时应显示不同的导航控制器内容.如果用户调出菜单并做出不同的选择,他当前正在操作的导航控制器不应该受到影响;新选择的导航链显示在旧导航链的顶部,通过菜单,用户可以随时返回上一个导航链离开的视图.
Each menu button, when pressed, should display a different navigation controller's content. If the user brings up the menu and makes a different selection, the navigation controller in which he is currently operating should not be affected; the newly selected navigation chain is displayed on top of the old, and through the menu, the user can go back to the view where he left off on the previous navigation chain at any time.
视觉插图(点击查看更高分辨率):
visual illustration (click for higher resolution):
请注意,有 3 种不同的导航控制器/链.根视图控制器(也是这个简化版本中的菜单)不是其中任何一个的一部分.当导航链之前已实例化时,重新实例化其中一个导航链是不够的,原因如下:如果用户在选项 2 的屏幕 3 上,然后从菜单中选择选项 1,然后(再次)从菜单,他应该正在查看选项 2 的屏幕 3——就在他离开的地方;他之前离开导航链时正在查看的视图控制器应该被带回顶部.
Please note that there are 3 different navigation controllers/chains. The root view controller (which is also the menu in this simplified version) is not part of any of them. It will not suffice to instantiate one of the navigation chains anew when it has been previously instantiated, and here's why: if the user was on screen 3 of option 2 and then selects option 1 from the menu and then selects option 2 (again) from the menu, he should be looking at screen 3 of option 2--right where he left off; the view controller he was viewing when he previously left the navigation chain should be brought back to the top.
如果没有导航控制器,我可以使按钮实例化并从情节提要中呈现视图控制器:
I can make a button instantiate and present a view controller from the storyboard if there is NOT a navigation controller:
- (IBAction)buttonPressed:(id)sender {
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"View 2"];
[self presentViewController:controller animated:YES completion:nil];
}
但是,我不知道如何使这两种方法与涉及的导航控制器一起工作.此外,我不确定这两种方法是不是正确的选择,因为我不会总是想实例化一个新的视图控制器:当按下菜单按钮时,应该执行检查以查看视图(导航?)具有相应标识符的控制器已经被实例化.如果是这样,它应该简单地成为顶视图控制器.
However, I can't figure out how to make those two methods work with a navigation controller involved. Moreover, I'm not sure those two methods are the right choice, because I won't always want to instantiate a new view controller: when a menu button is pressed, a check should be performed to see if the view (navigation?) controller with the corresponding identifier has already been instantiated. If so, it should simply be made the top view controller.
总之,这是我的问题:
1) 我应该如何实例化和显示嵌入在导航控制器中的视图控制器,最好使用情节提要 ID?您使用的是导航控制器还是视图控制器的情节提要 ID?
1) How should I instantiate and display a view controller that is embedded in a navigation controller, preferably using a storyboard ID? Do you use the storyboard ID of the navigation controller or of the view controller?
2) 我应该如何检查一个实例是否已经存在?同样,我应该检查现有的导航控制器还是视图控制器,最好的方法是什么?
2) How should I check whether an instance already exists? Again, should I check for an extant navigation controller or for a view controller, and what's the best method to do so?
3) 如果选定的导航链已经被实例化并且在某个视图控制器的堆栈中,那么将其置于顶部的最佳方法是什么?
3) If the selected navigation chain has already been instantiated and is in the stack of view controllers somewhere, what is the best method for bringing it to the top?
谢谢!!
旁注——如果知道如何粘贴保留缩进和颜色格式的代码片段会很高兴:)
side note -- it would be nice to know how to paste code snippets with indentation and color formatting preserved :)
正如 Rob 所建议的,标签栏控制器将为您的设计提供良好的组织原则.
As Rob has suggested, a tab bar controller would make a good organising principle for your design.
添加一个 UITabBarController 到你的故事板,给它一个故事板 ID.将三组 viewController(及其各自的 navController)中的每组分配给 tabBarController 中的一个选项卡项.
Add a UITabBarController to your storyboard, give it a storyboard iD. Assign each of your three sets of viewControllers ( with their respective navController) to a tab item in the tabBarController.
UITabBarController
|--> UINavigationController --> VC1 ---> VC2 -->
|--> UINavigationController --> VC1 ---> VC2 -->
|--> UINavigationController --> VC1 ---> VC2 -->
在您的应用程序委托中创建一个强大的属性来保存您的标签栏控制器的指针.由于选项卡栏控制器保留指向其所有选项卡项的指针,这将处理您的每组视图控制器的状态.您不必为它们中的任何一个保留单独的指针,并且可以通过 tabBarController 的 viewControllers
属性获取对它们的引用.
In you app delegate make a strong property to hold your tab bar controller's pointer. As the tab bar controller keeps pointers to all of it's tab items, this will take care of state for each of your sets of viewControllers. You won't have to keep separate pointers for any of them, and you can get references to them via the tabBarController's viewControllers
property.
@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 的属性检查器中选中在推送时隐藏底部栏"框.您不必为后续的 viewController 执行此操作,只需在该选项卡项中看到的第一个即可.
An alternative way to hide the tab bar is to check the "Hides bottom bar on push" box in the Attributes Inspector for each of the (initial) viewControllers. You don't have to do this for subsequent viewControllers, just the first one that will be seen in that tab item.
然后,当您需要导航到您的导航控制器组之一时……
Then when you need to navigate to one of your navController groups…
- (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
,您的应用设计可能会以其他方式导航...)
(this example uses presentViewController
, your app design may navigate this in other ways…)
更新
如果您想在没有标签栏控制器的情况下执行此操作,则可以实例化一个包含指向每个导航控制器的指针的数组:
If you want to do this without a tab bar controller, you can instantiate an array holding pointers to each of your nav controllers instead:
UINavigationController* ncA =
[storyboard instantiateViewControllerWithIdentifier:@"NCA"];
UINavigationController* ncB =
[storyboard instantiateViewControllerWithIdentifier:@"NCB"];
UINavigationController* ncC =
[storyboard instantiateViewControllerWithIdentifier:@"NCC"];
self.ncArray = @[ncA,ncB,ncC];
没有标签栏可隐藏的好处……
Which has the benefit of not having a tab bar to hide…
那么你的选择看起来像……
Then your selection looks like…
- (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];
}
这篇关于如何使用情节提要 ID 显示各种视图控制器(每个都有其各自的导航控制器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!