【问题标题】:moving between view controllers在视图控制器之间移动
【发布时间】:2014-12-30 20:44:46
【问题描述】:

基本上我有 4 个普通的视图控制器,其中一个是保存主要内容的“主”视图控制器。其他三个用于检查通知,创建新内容等。问题是 - 我只想加载一次主视图控制器(当应用程序启动时),所以当我在视图控制器之间导航时,要到达'home' 控制器我只是从视图中删除当前控制器

[self dismissViewControllerAnimated:NO completion:nil];

这意味着主控制器必须始终落后于当前控制器。所以总结一下 - 当从家搬到三个控制器中的任何一个时,我用

加载控制器
UIViewController *vc=[self.storyboard instantiateViewControllerWithIdentifier:@"RepliesView"];
                         [self presentViewController:vc animated:NO completion:nil];

当我从三个控制器中的任何一个移动到家时,我会关闭当前的视图控制器。如果我继续在主控制器和另一个控制器之间移动,这很好,但是当我从不在家的视图控制器移动到也不在家的视图控制器时会出现问题,所以基本上加载控制器同时需要然后关闭当前一个,以便加载的那个在后面有家庭控制器(因此可以被解雇回家)。到目前为止,我已经尝试过解散然后呈现

[self dismissViewControllerAnimated:NO completion:nil];
                     UIViewController *vc=[self.storyboard instantiateViewControllerWithIdentifier:@"RepliesView"];
                     [self presentViewController:vc animated:NO completion:nil];

但这给出了“视图不在窗口层次结构中!”警告并且出现的视图不是正在实例化的视图,而是主视图。如果有人可以提出解决方案,那就太棒了

【问题讨论】:

  • 那个问题是你不能从你刚刚解散的视图控制器中呈现,所以你要么必须从你的主视图呈现视图,或者不是解散然后呈现,你可以简单地呈现第二个视图,但当您想返回时一次关闭两个视图控制器。
  • 那么有没有办法可以从不同的视图控制器中关闭视图控制器,例如不是 [selfdismissView...] 而是 [aViewControllerdismiss...] ?
  • 我认为你应该连续呈现 2 个然后直接关闭到主视图控制器。
  • 因为后退两个视图控制器可以一步完成,而后退再前进则不行。
  • 主视图控制器是第一个视图控制器吗?

标签: ios objective-c uiviewcontroller


【解决方案1】:

我已经对此进行了一些研究并自己做了一些实验,它似乎完成了你想要完成的事情,你不应该使用模态视图控制器,而是应该将你的视图直接添加到导航堆栈。不要使用presentViewController:dismissViewController:,而是使用pushViewController:popViewController

因此,为了保持代码的初衷,您可以使用以下命令从主视图推送到任何视图控制器:

UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"RepliesView"];
[self.navigationController pushViewController:vc animated:NO];

然后使用任一使用关闭

[self.navigationController popViewControllerAnimated:NO];

或使用

[self.navigationController popToRootViewControllerAnimated:NO];

从堆栈中的任何视图控制器,只要您的“主”视图控制器是根视图控制器。

然后以您当前尝试的方式关闭并立即呈现,您可以推送而不是立即从堆栈的保留副本中弹出:

UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"RepliesView"];
UINavigationController *navController = self.navigationController;

[navController popViewControllerAnimated:NO];
[navController pushViewController:vc animated:NO];

只要您不想为过渡设置动画,这应该可以。

如果您确实想要为过渡设置动画,我建议您立即推送到vc,然后在您准备好返回“主页”视图时执行popToRootViewControllerAnimated:

【讨论】:

  • 我不确定我是否做错了什么,但我似乎无法正常工作。我在 appDelegate 中将主视图控制器设置为根控制器,当我尝试弹出视图控制器以返回主视图时,似乎什么也没发生(所以转换永远不会发生)。
  • @RodMatveev 您在使用 pushViewController 进行转换吗?
  • 不适合搬回家,因为我认为您必须使用 popViewController 删除当前控制器并到达家庭控制器。
  • @RodMateev 哦,我明白你为什么感到困惑了...我忘记将代码从 presentViewController 更改为 pushViewController。更新。是的,您必须使用popViewControllerpopToRootViewController 才能返回主视图,但您的代码中任何有presentViewController 的地方都必须更改为pushViewController
  • @RodMatveev 具体来说,[self.navigationController pushViewController:vc animated:NO];
【解决方案2】:

不是 100% 确定这是否可行,但请尝试一下:

[self dismissViewControllerAnimated:NO completion:^{
    UIViewController *vc=[self.storyboard instantiateViewControllerWithIdentifier:@"RepliesView"];
    [self.parentViewController presentViewController:vc animated:NO completion:nil];
}];

您遇到了问题,因为您尝试从已被驳回的 vc 中呈现 vc。但是,如果您从被解雇的 vc 的父 vc 中呈现它,那可能会做到这一点

编辑: 也不确定这是否会因为它有点hacky,但值得一试。在每个不在家的视图控制器中,像这样关闭它们:

[self dismissViewControllerAnimated:NO completion:^{
    UIViewController *vc=[self.storyboard instantiateViewControllerWithIdentifier:@"RepliesView"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ViewControllerDidDismiss" object:vc];
}];

在你的主视图控制器中,监听通知:

[[NSNotificationCenter defaultCenter] addObserverForName:@"ViewControllerDidDismiss"
                                                  object:nil
                                                   queue:[NSOperationQueue currentQueue]
                                              usingBlock:^(NSNotification *note) {
                                                  UIViewController *vc = [note object];
                                                  [self presentViewController:vc animated:NO completion:nil];
                                              }];

【讨论】:

  • 我已经尝试过了,但就像在出现“home”控制器而不是“RepliesView”之前一样
  • @RodMatveev 我想出了另一个想法让你尝试从不同的方法。查看我的编辑
  • 这确实有效,但您实际上可以在 repliesView 出现之前看到主控制器(它有点闪烁大约半秒),有什么办法可以解决这个问题吗?
  • 实际上它似乎只在第一个周期闪烁,当我第二次浏览你的代码时,flash 更短,之后repliesView 直接加载......
  • 玩弄它,看看你能想出什么。我不知道你会如何防止它闪烁,这只是导航流程不一致的结果。我没有想到这个实现,但可能以编程方式截取视图的屏幕截图你要从家里去,把它覆盖在家里的图像视图中,当你关闭新视图时,屏幕截图会让它看起来还在那里。然后对其他视图做同样的事情,并在回家时隐藏图像视图
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多