我可以在这里找到一个我非常喜欢的图书馆(https://github.com/pixyzehn/MediumMenu)。
基本上它执行以下操作:
后面的菜单实际上是一个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我希望菜单上的这个功能不是初始视图控制器?
答案 0 :(得分:3)
简短回答是:是。
这可以通过为包含UIViewControllerTransitioningDelegate
的{{1}}分配ViewController
并实施list-menu
和interactionControllerForPresentation()
方法来实现。您无需触摸interactionControllerForDismissal()
(直接)。
您可以更改此部分关于现有的UIWindow
,但从它的外观来看,它只是一个带有奇特过渡的library
。你可以自己轻松实现这一点。
查看Apple的API Reference关于交互式过渡和this tutorial的Ray Wenderlich的实例。
答案 1 :(得分:2)
所以很明显你的情况是:
rootViewController
= a UINavigationController
rootViewController
的{{1}}是LoginController UINavigationController
推送(或segue)到menuController 或
navigationController
是LoginController 所以关键点是获取一个menuController而不是将其设置为应用的rootViewController
。
以下是我根据您的要求进行了一些更改的代码。 https://github.com/Moonsownner/MediumMenu-master
我做了什么:
rootViewController
实际上是MediumMenu
,我们必须创建一个控制器来包含它,以便进行转换。所以我创建了一个名为UIView
的新类。你可以看到我将函数MediumMenuController
移动到showMenu
。因此,如果有人想要手动显示菜单,则目标必须是MediumMenuController而不是之前的MediumMenuController
。 NavigationController
将包含您发送到MediumMenuController
初始函数的业务控制器。MediumMenuController
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()
}
}
。让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
将始终存在。
希望这有帮助!