我对iOS开发完全不熟悉,但仍未完成如何完成这么简单的任务。
我有一个原始的xCode 4.4.1“单一视图应用程序”项目。
我想要有四个屏幕,每个屏幕都有用于切换到其他视图的按钮。
屏幕在层次结构中设置不:例如,我希望能够从屏幕1切换到屏幕2或屏幕3,从屏幕2切换到屏幕4,依此类推。在应用程序运行时 - 显示第一个屏幕,但其状态不是“root”或“main” - 它只是一个常见的屏幕等。
我的条件是:
在我看来,我需要以某种方式设置带有子控制器的Container控制器,因为它们在WWDC 2011的Session 102中有描述,但我不明白如何正确编写代码,所以它不会与主要故事板(我有两次尝试使用其他类似主题的基于xib的解决方案)。
我非常感谢一个完整的工作示例,因为我的经验还不允许我依赖部分提示,尽管它们也会很好。
首选的是以编程方式执行此操作的解决方案(不使用拖动等xCode UI功能)。
谢谢!
更新:切换时,我不希望每次都实例化新屏幕,但如果它们已经存在,则重新使用现有屏幕。
更新2:我的用例,针对此问题进行了简化:
我有一个注册屏幕,有相应的模态屏幕来处理所有常见的登录/注销/等情况。我有我的应用程序的主屏幕,登录/注册程序完成后成为“主”应用程序屏幕。我不想让注册屏幕/控制器成为主屏幕的模态,因为主屏幕几乎取决于用户特定的信息,所以我希望这些屏幕不以任何方式组织在层次结构中。我想为这种简化的情况提供以下流程:
1)用户尚未登录 - 显示注册屏幕。之后,reg。程序完成 - 切换(这是我不知道的关键点,这就是为什么这个问题)到“主”屏幕。
2)用户已登录并被应用程序识别 - 显示“主”屏幕。
如我所描述的那样注册和“主要”屏幕排除了(或什么?)在“选项卡式应用程序”模板中具有“标签控制器”功能的情况,因为在我的情况下我想要完全禁用标签栏 - 我需要的不是导航。 &安培;导航栏功能,但只是在reg之间执行转换的方式。和“主要”屏幕 - 在我的问题中,这就是我所说的“用手”。
最终更新:
在使用标签栏控制器进行实验之后,对于这个用例,我最终使用了导航控制器并禁用了导航栏(我在Tab栏控制器中找不到类似的一个)并通过管理屏幕切换performSegueWithIdentifier 方法以及通过“手动”操作 viewControllers 导航堆栈来切换它们。
谢谢大家的答案!
答案 0 :(得分:2)
最容易做的事情可能就是在故事板中使用segues。
右键单击并从主视图控制器拖动到其他每个控制器。它将询问要创建什么类型的segue,并选择模态。
然后,确保在identifier属性中为每个segue分配一个唯一的标识符字符串。
现在,从代码中,只要您希望其中一个视图控制器变为活动状态,就可以调用
[self performSegueWithIdentifier:@"Foo Segue" sender:(id)sender];
上面的发件人对象可以是您想要的任何内容,通常是您希望传递给准备显示的视图控制器的一些信息。
现在,就在显示segue之前,无论是以编程方式还是直接从storyboard定义的交互,都会调用prepareForSegue
方法。那么,您将再次在“主”视图控制器的代码中执行类似的操作。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// You have access to the view controller that is getting ready to be
// displayed, as well as the identifier, so you can set values or whatever
// before the view controller is presented.
if ([segue.identifier isEqualToString:@"Foo Segue"]) {
FooViewController *vc = segue.destinationViewController;
// The view controller is completely instantiated, and you can do any
// setup work, like setting property values on the view controller
// to give it its model, or whatever else you want to do.
}
}
现在,您需要一些方法来了解控制器何时完成。这可以通过几种方式完成。呈现的视图控制器可以解除其自身,或者可以使用委托或通知来告知呈现视图控制器已完成且应该被解除。
在你的情况下,让所呈现的VC解雇自己可能会很好。所以,只需致电
[self dismissViewControllerAnimated:YES completion:nil];
如果您不想使用segues,则必须直接从故事板加载VC(或者给他们自己的笔尖)。要从故事板中实例化,您必须为要实例化其自己的标识符标记的视图控制器提供(再次查看属性窗格并在VC上设置属性)。
然后你可以这样做(假设存放此代码的VC与它试图实例化的VC在同一个故事板中)......
FooViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"FooViewController"];
然后,您实际使用...
呈现该控制器[self presentViewController:vc animated:YES completion:nil];
当然,还有其他几种方法可以做到这一点,每种方法都有一些优点/缺点。我建议您使用它并阅读相关文档,以便您可以就使用哪种方法做出明智的决定。
无论如何,上述内容应该为您提供一条轻松实现目标的途径。
答案 1 :(得分:2)
您的问题的简短回答是使用标签栏控制器。这是一个外部简单的控件,实际上管理了很多复杂性,对于初学者或应用程序的用户来说,重新实现它并不是一个好主意,他们将习惯标签栏控制器的工作方式。
标签栏控制器有一个属性(viewControllers
),您可以通过控制拖动到其他场景来填充故事板。标签栏控制器询问每个视图控制器以构建标签栏(名称和图像,适当数量的项目,如果有太多不适合栏上的“更多”控制器)并处理它们之间的切换,更改包含的视图的大小和标签栏以处理旋转事件。因此,标签栏控制器的视图包含两个子视图 - 一个用于保存标签栏,另一个用于保存当前显示的视图控制器的视图。
您需要自己复制所有这些功能,这对初学者来说非常复杂,当然不在Stack Overflow答案的范围内。您要复制现有功能的事实也应该是一个红旗,如果您真的应该以这种方式工作。
故事板也不支持自己实现标签栏类型控制器,因为关键部分(“关系 - 视图控制器”)不适用于自定义容器视图控制器。因此,您必须在代码中设置UI并手动实例化视图控制器以建立关系,这可能会与您的主故事板发生冲突 - 尽管您的句子更倾向于以编程方式对故事板请求进行冲突。问题标题,所以我有点困惑。
如果您仍想要 如何实现此目的的简要概述:
viewControllers
属性后,获取标题以设置为您的某个分段控制段的标题。将数组中第一项的视图添加为主视图的子视图(使用适当的框架,使其不覆盖您的分段控件),并使用[self addChildViewController:vc]
和{{1将其添加为子视图控制器}})[vc didMoveToParentViewController:self]
)和视图控制器层次结构(removeFromSuperview
)中删除当前视图控制器的视图,并使用新添加的视图控制器视图添加上面的代码。