使用 Storyboard 时对 prepareforsegue 和 presentModalViewController 的说明

Posted

技术标签:

【中文标题】使用 Storyboard 时对 prepareforsegue 和 presentModalViewController 的说明【英文标题】:Clarification on prepareforsegue and presentModalViewController while using Storyboard 【发布时间】:2013-05-09 21:58:54 【问题描述】:

我有一个以 LoginViewController 作为初始视图的应用程序。

注意: 所以在 appDelegate.m 中,self.window.rootViewController 不是 TabBarController。

在 Auth 之后,我展示了应用程序的主要部分,它有一个带有两个选项卡的 tabbarController (identifier:tabBar),一个选项卡有一个导航控制器。我正在使用Core Data,所以我需要通过MOC。

如果我使用,

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UITabBarController *obj=[storyboard instantiateViewControllerWithIdentifier:@"tabBar"];
[obj setSelectedIndex:0];// Which tab to show first
[self presentModalViewController:obj animated:YES];

它在视觉上效果很好。现在我需要通过 MOC。阅读 PrepareToSegue 方法,创建从 loginVC 到我的 TargetViewController (TabBar>NavigationController1>View1) 的 segue(模态,图中未显示),将 segue 命名为“LoginSegue”并使用以下代码:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

UINavigationController *navController = (UINavigationController *)[segue destinationViewController];
View1 *devicelist = (View1 *)[[navController viewControllers] lastObject];
devicelist.managedObjectContext = managedObjectContext;

TabBar 不显示。在这种情况下如何设置标签栏控制器?

我一直在尝试获取 Modal Tabbar 的参考信息,但仍不清楚。有人可以用外行的方式解释如何处理这种情况吗?

【问题讨论】:

你说你展示了标签栏控制器,所以在那之后,屏幕上的视图应该是我认为你正在调用目标视图控制器(TabBar>NavigationController1>View1)的视图。所以,如果这是真的,那你为什么要从登录控制器转移到你已经在屏幕上的那个? @rdelmar 屏幕上的初始视图是 loginScreen。我(想)仅在用户登录后才显示 tabbarController>NavigationController>View1。这就是为什么我尝试从登录屏幕转到 view1。 【参考方案1】:

我认为最好使用不使用模式转换到标签栏控制器的设计。模态演示通常应该是为了中断应用程序的正常流程,而不是为了让你的主控制器出现在屏幕上。有两种选择,我认为更好。您可以将登录控制器保留为窗口的初始根视图控制器,然后将其切换为选项卡栏控制器(它将成为窗口的新根视图控制器,并且登录控制器将被释放)。这通常可以正常工作,但我认为在这种情况下,如果您想将 MOC 从应用程序委托(我假设)传递到选项卡栏控制器中的控制器,我认为第二种方式会更好。

第二种方法,也是我通常做登录控制器的方法,是让标签栏控制器成为窗口的根视图控制器,然后从初始视图的 viewDidAppear 方法模态地呈现登录控制器(这将是您调用 View1 的那个)。如果您在动画设置为 NO 的情况下进行演示,登录控制器将是用户看到的第一件事:

-(void)viewDidAppear:(BOOL)animated 
    [super viewDidAppear:animated];
    static int first = 1;
    if (first) 
        LoginViewController *login = [self.storyboard instantiateViewControllerWithIdentifier:@"Login"];
        [self presentViewController:login animated:NO completion:nil];
        first = 0;
    

if 语句在那里,因此当您从登录控制器返回时,演示不会再次发生(您可以做一些更复杂的事情,例如从登录控制器返回 View1 的委托,表明登录成功如果你愿意,但这是可行的)。

如果登录成功,您只需关闭登录控制器,您就会在第一个视图中出现(如果失败,您永远不会关闭它,并且可能会显示一条消息说登录失败)。

如果你走这条路,那么你可以像这样在应用委托中传递 MOC:

UINavigationController *nav = [(UITabBarController *)self.window.rootViewController viewControllers][0];
View1 *devicelist = (View1 *)nav.viewControllers.lastObject;
devicelist.managedObjectContext = managedObjectContext;

【讨论】:

感谢您的评论。我明白你的意思了。我试过了,它的工作原理。但只是想知道,如果标签栏以模态方式呈现,是否有可能告诉我如何到达 tabbarcontroller>navController>View1?在了解更多之后,我感到轻松切换路径。 :) 如果您从登录控制器进行演示,则问题中的前 3 行应在屏幕上显示带有 View1 的选项卡栏。或者,您可以使用 segue 来完成,但您需要将 segue 从登录控制器连接到标签栏控制器,而不是导航控制器。

以上是关于使用 Storyboard 时对 prepareforsegue 和 presentModalViewController 的说明的主要内容,如果未能解决你的问题,请参考以下文章

在 didSelectRowAtIndexPath 之后 prepareForSegue?

使用 Storyboard 时不通过 Storyboard 推送 ViewController

使用 CommandManager 时对 ICommand.CanExecute 进行单元测试

使用 FBSDKApplicationDelegate 时对成员“下标”的模糊引用

使用 Objective-C 快速枚举时对 NSManagedContext 对象执行保存操作是不是安全

IOS多语言切换2-storyboard