QQ 抽屉样式左右侧滑菜单-QDrawerController

QQ 抽屉样式左右侧滑菜单-QDrawerController
之前项目中实现抽屉样式左右侧滑菜单都是在使用 MMDrawerController,一个轻量、使用简单的框架,向经典致敬!
在重构老项目时要使用 swift 语言,就想着用swift实现这个这功能,在学习了 MMDrawerController 源码和一些博客文章,决定动手。

实现思路
  • 在 QDrawerController 中使用 addChildViewController 方法,添加左中右三个ViewController并调整响应初始坐标位置。
    图层顺序:window -> QNavigationController -> leftViewController ->centerViewController -> rightViewController
  • QNavigationController view 添加边缘侧滑手势,以手势滑动的值控制页面的 x 轴。
  • centerViewController 添加遮罩层,透明度根据手势滑动值控制
效果

上图
QDrawerController.gif
  • 效果还可以,由于使用 QDrawerController 为基础层,会影响到 StatusBar 的自定义设置,所以需要 childViewControllerForStatusBarStyle 返回对应的 ViewController,
// MARK: - 状态栏变化处理 ******************
    enum QDrawerSide {
        case none
        case left
        case right
    }
    private var openSide: QDrawerSide? = QDrawerSide.none {
        didSet{
            setNeedsStatusBarAppearanceUpdateIfSupported()
        }
    }
    override var childViewControllerForStatusBarStyle: UIViewController? {
        return getTopViewController()
    }
    override var childViewControllerForStatusBarHidden: UIViewController? {
        return getTopViewController()
    }
    private func childViewControllerForSide(drawerSide: QDrawerSide) -> UIViewController {
        switch drawerSide {
        case .left:
            return leftDrawerVC!
        case .right:
            return rightDrawerVC!
        case .none:
            return centerVC!
        }
    }
    private func setNeedsStatusBarAppearanceUpdateIfSupported() {
        if responds(to: #selector(setNeedsStatusBarAppearanceUpdate)) {
            self.perform(#selector(setNeedsStatusBarAppearanceUpdate))
        }
    }
    private func getTopViewController() -> UIViewController {
        if self.childViewControllerForSide(drawerSide: openSide!) == centerVC {
            if centerVC is UITabBarController {
                for vcs in (centerVC?.childViewControllers)! {
                    if vcs is UINavigationController {
                        return (vcs as! UINavigationController).topViewController!
                    } else {
                        return vcs
                    }
                }
            } else if centerVC is UINavigationController {
                return (centerVC as! UINavigationController).topViewController!
            } else {
                return self.childViewControllerForSide(drawerSide: openSide!)
            }
        }
        return self.childViewControllerForSide(drawerSide: openSide!)
    }

完美解决 StatusBar 的自定义设置。因为使用了几个手势,所以需要特别处理一下手势的冲突问题(就不上代码了,看源码吧)。

使用

使用起来很简单

初始化方法
init(centerVC: UIViewController, leftDrawerVC: UIViewController, maxLeftDrawerWidth: CGFloat)
init(centerVC: UIViewController, rightDrawerVC: UIViewController, maxRightDrawerWidth: CGFloat)
init(centerVC: UIViewController, leftDrawerVC: UIViewController, maxLeftDrawerWidth: CGFloat, rightDrawerVC: UIViewController, maxRightDrawerWidth: CGFloat)
设置 centerViewController
open func setCenterVC(newCenterVC: UIViewController)
跳转到某个页面
open func didSelectedVC(didSelectedVC: UIViewController)
打开左侧页面
open func openLeftDrawer()
打开右侧页面
open func openRightDrawer()
  • 给 UIViewController 增加了 extension ,方便调用打开侧页面方法
// MARK: - UIViewController 扩展,方便调用 QDrawerController 
extension UIViewController {
    var q_drawerController: QDrawerController {
        var drawerController: QDrawerController?
        
        var parentVC = self.parent
        while parentVC != nil {
            if parentVC is QDrawerController {
                drawerController = parentVC as? QDrawerController
            }
            parentVC = parentVC?.parent
        }
        return drawerController!
    }
}

// 使用时如下
self.q_drawerController.openRightDrawer()
self.q_drawerController.setCenterVC(newCenterVC: UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()!)
self.q_drawerController.setCenterVC(newCenterVC: BViewController())
self.q_drawerController.didSelectedVC(didSelectedVC: CViewController())
结语

QDrawerController 也很简单,目前测试检测未发现 Bug,但肯定会有考虑不周之处,请朋友们多多指正。
奉上源码地址 QDrawerController

你可能感兴趣的:(QQ 抽屉样式左右侧滑菜单-QDrawerController)