【问题标题】:Present new view controller and invisibly dismiss the current chain of presented view controllers呈现新的视图控制器并无形地关闭当前呈现的视图控制器链
【发布时间】:2016-02-11 14:36:43
【问题描述】:

所以我有一个视图控制器链(通常是 2 - 3 个),其中第一个是根视图控制器,下一个是 presentViewController:animated:

这是应用程序的载入部分,当用户最终到达我需要显示主 UI 的部分时,我想在显示之前关闭所有载入视图控制器(根视图控制器除外)主 UI 视图控制器是 UITabBarController。 我想这样做的原因是 - 我不再需要它们,而且我不希望将那些视图控制器保留在内存中。

现在的问题是 - 我希望这看起来像我只是在呈现 UITabBarController,我不希望用户看到以前的视图控制器被解雇。

我尝试的第一件事:

  1. 使用animated: NO 在根视图控制器上调用dismissViewControllerAnimated:completion:
  2. 完成后使用presentViewController:animated:completion:animated: YES 显示我的UITabBarController

可悲的是,在显示呈现我的 UITabBarController 的动画之前闪烁的根视图控制器。

我尝试过的复杂解决方案:

  1. 拍摄主窗口的快照
  2. 添加快照作为根视图控制器视图的子视图
  3. 在根视图上调用dismissViewControllerAnimated:completion: 控制器animated: NO
  4. 完成后使用presentViewController:animated:completion:animated: YES 显示我的UITabBarController
  5. presentViewController: 完成后,从根视图控制器的视图中删除快照视图

这是执行此操作的代码。它有点复杂,因为它还处理弹出根视图控制器的子视图控制器,因为根视图控制器是 UINavigationController:

- (void)popNavToRootAndPresentViewController:(UIViewController *)viewController
{
    UINavigationController *rootVC = (UINavigationController *)self.view.window.rootViewController;

    // if we have a chain of presented view controllers over our nav vc, then we need to dismiss them
    if (rootVC.presentedViewController) {
        // we need a snapshot view because even if dismissing without animation, root view controller will flash for a fraction of a second.
        __block UIView *snapShotView = [self.view.window snapshotViewAfterScreenUpdates:NO];

        [rootVC.view addSubview:snapShotView];

        // hide the currently presented view controller chain without animation. This won't be visible since we've added the snapshot on the rootVC
        [rootVC dismissViewControllerAnimated:NO completion:^{

            // present the new view controller that we need
            [rootVC presentViewController:viewController animated:YES completion:^{
                // pop to root in case there are more than one pushed to nav stack
                [rootVC popToRootViewControllerAnimated:NO];
                // we don't need the snapshot view anymore
                [snapShotView removeFromSuperview];
            }];

        }];
    } else {
        [rootVC presentViewController:viewController animated:YES completion:^{
            // we presented our vc from the nav vc, so we can pop the nav vs itself to root - that won't be noticable
            [rootVC popToRootViewControllerAnimated:NO];
        }];
    }

}

即使插入当前视图层次结构的快照,我仍然有闪烁。 使用此解决方案,dismissViewControllerAnimated 会导致视图控制器短暂闪烁,该视图控制器是链中的前一个(一个展现自我的人)。

有没有一种方法可以在不闪烁的情况下实现预期的结果?我想这样的事情可以通过自定义父视图控制器和子视图控制器来实现,从那时起就可以更好地控制视图的方式已被替换,但我真的很想保持简单并使用presentViewController:

【问题讨论】:

  • 首先你的根视图控制器是什么?你说你的根视图控制器是 UINavigationController 这是完全错误的。导航控制器只会有其他视图控制器作为它们的根视图,它们不是它们自己的根视图。
  • 是的,UINavigationController 是 UIWindow 的根视图控制器。正如我在提供的代码示例中进行的那样:(UINavigationController *)self.view.window.rootViewController。它不是另一个导航控制器的根视图控制器。我们正在谈论的不同类型的“根视图控制器”。

标签: ios objective-c iphone uiviewcontroller


【解决方案1】:

您可以简单地将标签栏控制器呈现(动画)在所有其他控制器之上,一旦动画完成,您可以将所有控制器解散回根并再次呈现标签栏控制器,这次不是动画.

确保您保留对标签栏控制器的引用,这样您就不必重新分配新版本。

【讨论】:

  • 我认为这行不通。如果我在当前呈现的视图控制器之上呈现标签栏控制器,那么我不能在不关闭新呈现的标签栏控制器的情况下关闭其余部分。如果我在根 vc 上调用dismissViewController,它将关闭所有链,包括标签栏控制器。
猜你喜欢
  • 2017-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多