如何不使用Storyboards和CocoaPods实现类KYDrawerController的侧滑菜单?
嘿,我来帮你捋捋这个问题~
方案一:纯代码手动实现侧滑菜单
如果你想自己从零搭建,核心是做一个容器ViewController来管理主界面和侧滑菜单,以下是关键步骤:
第一步:搭建基础容器结构
创建一个容器VC,把主VC和菜单VC都作为子VC添加进去。初始状态下,菜单VC藏在屏幕左侧外面,主VC占满整个屏幕。
示例代码:class DrawerContainerVC: UIViewController { // 自定义菜单宽度,可根据需求调整 let menuWidth: CGFloat = 280 private var menuVC: MenuViewController! private var mainVC: UIViewController! override func viewDidLoad() { super.viewDidLoad() setupMainViewController() setupMenuViewController() } private func setupMainViewController() { // 替换成你的初始主视图控制器 mainVC = YourInitialMainVC() addChild(mainVC) mainVC.view.frame = view.bounds view.addSubview(mainVC.view) mainVC.didMove(toParent: self) } private func setupMenuViewController() { // 替换成你的菜单视图控制器 menuVC = YourMenuVC() addChild(menuVC) // 初始位置:完全藏在左侧 menuVC.view.frame = CGRect(x: -menuWidth, y: 0, width: menuWidth, height: view.bounds.height) view.addSubview(menuVC.view) menuVC.didMove(toParent: self) } }第二步:添加侧滑手势交互
给主VC的视图添加拖动手势,根据手势偏移量调整菜单的位置,同时给主VC加一点缩放动画增强视觉效果:// 在DrawerContainerVC的viewDidLoad里添加手势 override func viewDidLoad() { super.viewDidLoad() setupMainViewController() setupMenuViewController() addPanGesture() } private func addPanGesture() { let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:))) mainVC.view.addGestureRecognizer(panGesture) } @objc private func handlePanGesture(_ gesture: UIPanGestureRecognizer) { let translation = gesture.translation(in: view) var currentMenuX = menuVC.view.frame.origin.x switch gesture.state { case .changed: // 限制菜单只能在[-menuWidth, 0]范围内移动 currentMenuX = max(-menuWidth, min(currentMenuX + translation.x, 0)) menuVC.view.frame.origin.x = currentMenuX // 主VC随菜单展开比例缩放,增强层次感 let scaleRatio = 1 - (abs(currentMenuX)/menuWidth)*0.15 mainVC.view.transform = CGAffineTransform(scaleX: scaleRatio, y: scaleRatio) // 重置手势偏移,避免连续拖动时的累积问题 gesture.setTranslation(.zero, in: view) case .ended, .cancelled: // 手势结束时,根据菜单当前位置判断是完全展开还是收起 let shouldOpen = currentMenuX > -menuWidth/2 UIView.animate(withDuration: 0.3) { self.menuVC.view.frame.origin.x = shouldOpen ? 0 : -self.menuWidth self.mainVC.view.transform = shouldOpen ? CGAffineTransform(scaleX: 0.85, y: 0.85) : .identity } // 切换点击手势的启用状态 self.mainVC.view.gestureRecognizers?.first(where: { $0 is UITapGestureRecognizer })?.isEnabled = shouldOpen default: break } }第三步:添加菜单收起逻辑
可以给主VC添加点击手势,当菜单展开时,点击主VC区域自动收起菜单:// 在DrawerContainerVC的viewDidLoad里添加 override func viewDidLoad() { super.viewDidLoad() setupMainViewController() setupMenuViewController() addPanGesture() addTapToCloseGesture() } private func addTapToCloseGesture() { let tapGesture = UITapGestureRecognizer(target: self, action: #selector(closeMenu)) mainVC.view.addGestureRecognizer(tapGesture) // 初始时禁用点击,只有菜单展开后才启用 tapGesture.isEnabled = false } @objc private func closeMenu() { UIView.animate(withDuration: 0.3) { self.menuVC.view.frame.origin.x = -self.menuWidth self.mainVC.view.transform = .identity } completion: { _ in // 收起后禁用点击手势 self.mainVC.view.gestureRecognizers?.first(where: { $0 is UITapGestureRecognizer })?.isEnabled = false } }
方案二:直接使用KYDrawerController的评估
如果你纠结要不要用这个库,我给你分析下:
- 为什么值得用?
- 成熟省心:这个库已经经过大量项目验证,像屏幕旋转、手势冲突、边缘触发这些细节都处理好了,自己实现要花不少时间踩坑。
- 功能完善:除了基础侧滑,它还支持自定义抽屉宽度、手势灵敏度、甚至多方向抽屉,这些功能自己写的话得额外花精力。
- 解决你担心的Swift版本问题
不用CocoaPods就行!直接把KYDrawerController的源码文件拖进你的项目里,这样Swift更新后,你可以自己修改源码适配新版本——它的核心逻辑不算复杂,适配成本很低,完全不用等作者更新。
最终建议
- 如果你的项目时间紧张,或者不想在自定义容器VC上花太多精力,直接集成KYDrawerController源码是更高效的选择;
- 如果是想学习自定义容器ViewController的实现逻辑,或者需要高度定制的效果,那自己手动实现一遍会收获很多。
内容的提问来源于stack exchange,提问作者spoax
相关产品推荐
相关产品推荐

