有没有办法在不弄乱AppDelegate窗口的情况下查看另一个UIViewController后面的UIViewController?

时间:2016-09-17 07:18:20

标签: ios uiviewcontroller appdelegate uiwindow rootviewcontroller

我可以在这里找到一个我非常喜欢的图书馆(https://github.com/pixyzehn/MediumMenu)。

基本上它执行以下操作:

MediumMenu Demo

后面的菜单实际上是一个UIViewController。如果我们深入研究源代码,我们将找到以下非常重要的代码:

public init(items: [MediumMenuItem], forViewController: UIViewController) {
    self.init()
    self.items = items
    height = screenHeight - 80 // auto-calculate initial height based on screen size
    frame = CGRect(x: 0, y: 0, width: screenWidth, height: height)
    contentController = forViewController
    menuContentTableView = UITableView(frame: frame)
    menuContentTableView?.delegate = self
    menuContentTableView?.dataSource = self
    menuContentTableView?.showsVerticalScrollIndicator = false
    menuContentTableView?.separatorColor = UIColor.clearColor()
    menuContentTableView?.backgroundColor = menuBackgroundColor
    addSubview(menuContentTableView!)

    if panGestureEnable {
        let pan = UIPanGestureRecognizer(target: self, action: #selector(MediumMenu.didPan(_:)))
        contentController?.view.addGestureRecognizer(pan)
    }

    let menuController = UIViewController()
    menuController.view = self

   UIApplication.sharedApplication().delegate?.window??.rootViewController = contentController
   UIApplication.sharedApplication().delegate?.window??.insertSubview(menuController.view, atIndex: 0)
}

前几行并不重要,但最后几行(处理UIApplication.sharedApplication().delegate?.window??的行是这个库工作的关键,但它们也限制了库。

根据这些行,我们正在制作我们希望菜单为rootViewController的UIViewController,然后我们将菜单视图添加到0索引处的窗口(I' m猜测这就是把它放在后面,在contentController之后。

图书馆的问题:

只有在初始视图控制器上需要菜单时,该库才有效。从某种意义上说,只有contentController已经是rootViewController。它在我的应用程序中实际上对我有用,但我不能再回到我原来的UIViewController,因为它不再在层次结构中。

我有一个场景,我有一个登录视图控制器,当你成功登录时,我将你转到我想要菜单的UINavigationController。问题的第一个明显标志是我收到投诉"警告:尝试在ViewViewController上显示UINavigationController,其视图不在窗口层次结构中!" 显然,它不是&# 39; t在窗口层次结构中因为我重新分配了rootViewController。

我不知道如何解决这个问题。有没有办法让UIViewController我希望菜单上的这个功能不是初始视图控制器?

3 个答案:

答案 0 :(得分:3)

简短回答是:

这可以通过为包含UIViewControllerTransitioningDelegate的{​​{1}}分配ViewController并实施list-menuinteractionControllerForPresentation()方法来实现。您无需触摸interactionControllerForDismissal()直接)。

您可以更改此部分关于现有的UIWindow,但从它的外观来看,它只是一个带有奇特过渡的library。你可以自己轻松实现这一点。

查看Apple的API Reference关于交互式过渡和this tutorial的Ray Wenderlich的实例。

答案 1 :(得分:2)

所以很明显你的情况是:

  1. rootViewController = a UINavigationController
  2. rootViewController的{​​{1}}是LoginController
  3. 当有人登录成功时,UINavigationController推送(或segue)到menuController
    1. navigationController是LoginController
    2. 当有人登录成功时,会显示menuController
    3. 所以关键点是获取一个menuController而不是将其设置为应用的rootViewController

      以下是我根据您的要求进行了一些更改的代码。 https://github.com/Moonsownner/MediumMenu-master

      我做了什么:

      1. rootViewController实际上是MediumMenu,我们必须创建一个控制器来包含它,以便进行转换。所以我创建了一个名为UIView的新类。你可以看到我将函数MediumMenuController移动到showMenu。因此,如果有人想要手动显示菜单,则目标必须是MediumMenuController而不是之前的MediumMenuControllerNavigationController将包含您发送到MediumMenuController初始函数的业务控制器。
      2. MediumMenuController
        1. 我删除了class MediumMenuController: UIViewController { let menuView: MediumMenu let child: UIViewController init(items: [MediumMenuItem], childController: UIViewController){ self.menuView = MediumMenu(items: items, forViewController: childController) self.child = childController super.init(nibName: nil, bundle: nil) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() view.addSubview(menuView) addChildViewController(child) self.view.addSubview(child.view) child.view.frame = UIScreen.mainScreen().bounds child.didMoveToParentViewController(self) } func showMenu() { menuView.show() } }
        2. 中的代码
            

          让menuController = UIViewController(); menuController.view = self   UIApplication.sharedApplication()。委托?.window ?? RootViewController的   = contentController UIApplication.sharedApplication()。委托?.window ??。insertSubview(menuController.view,   atIndex:0)

          并创建一个名为MediumMenu的新控制器,以将MediumMenuController和其他控制器视图添加到其中。

          通过上述说法可能还不清楚。代码可以显示详细信息。祝你好运。

答案 2 :(得分:2)

您可以按照以下步骤实现。

(i)将LoginViewController作为rootViewController

(ii)当用户成功登录时,将用户重定向到主屏幕。这是您在成功登录后要显示的第一个屏幕。

(iii)您可以在其中显示要显示菜单的UIViewControllers的父类。

(iv)之后,当您初始化任何UIViewController时,父类将调用public init(items: [MediumMenuItem], forViewController: UIViewController)方法,并且您可以使用以下代码替换最后两行。 self.view.insertSubview(menuController.view, atIndex: 0)

(v)点击退出按钮时,您可以简单地关闭所提供的视图控制器,因此LoginViewController将始终存在。

希望这有帮助!