QQ 抽屜樣式左右側(cè)滑菜單-QDrawerController
之前項目中實現(xiàn)抽屜樣式左右側(cè)滑菜單都是在使用 MMDrawerController长捧,一個輕量、使用簡單的框架盒发,向經(jīng)典致敬!
在重構(gòu)老項目時要使用 swift 語言脖祈,就想著用swift實現(xiàn)這個這功能年局,在學(xué)習(xí)了 MMDrawerController 源碼和一些博客文章际看,決定動手。
實現(xiàn)思路
- 在 QDrawerController 中使用 addChildViewController 方法矢否,添加左中右三個ViewController并調(diào)整響應(yīng)初始坐標(biāo)位置仲闽。
圖層順序:window -> QNavigationController -> leftViewController ->centerViewController -> rightViewController - QNavigationController view 添加邊緣側(cè)滑手勢,以手勢滑動的值控制頁面的 x 軸僵朗。
- centerViewController 添加遮罩層赖欣,透明度根據(jù)手勢滑動值控制
效果
上圖QDrawerController.gif
- 效果還可以,由于使用 QDrawerController 為基礎(chǔ)層验庙,會影響到 StatusBar 的自定義設(shè)置顶吮,所以需要 childViewControllerForStatusBarStyle 返回對應(yīng)的 ViewController,
// MARK: - 狀態(tài)欄變化處理 ******************
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 的自定義設(shè)置。因為使用了幾個手勢粪薛,所以需要特別處理一下手勢的沖突問題(就不上代碼了悴了,看源碼吧)。
使用
使用起來很簡單
初始化方法
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)
設(shè)置 centerViewController
open func setCenterVC(newCenterVC: UIViewController)
跳轉(zhuǎn)到某個頁面
open func didSelectedVC(didSelectedVC: UIViewController)
打開左側(cè)頁面
open func openLeftDrawer()
打開右側(cè)頁面
open func openRightDrawer()
- 給 UIViewController 增加了 extension 汗菜,方便調(diào)用打開側(cè)頁面方法
// MARK: - UIViewController 擴(kuò)展让禀,方便調(diào)用 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())
結(jié)語
QDrawerController 也很簡單,目前測試檢測未發(fā)現(xiàn) Bug陨界,但肯定會有考慮不周之處巡揍,請朋友們多多指正。
奉上源碼地址 QDrawerController