美文网首页
QQ 抽屉样式左右侧滑菜单-QDrawerController

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

作者: 曦风兮 | 来源:发表于2017-11-30 11:50 被阅读54次

    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

          本文链接:https://www.haomeiwen.com/subject/kjzmbxtx.html