博客> QQ 抽屉样式左右侧滑菜单-QDrawerController
QQ 抽屉样式左右侧滑菜单-QDrawerController
2018-09-21 18:51 评论:0 阅读:944 qyfeng009
ios 侧滑菜单

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](https://github.com/qyfeng009/QDrawerController.git)
收藏
0
sina weixin mail 回到顶部