在最近的一個專案中需要製作一個抽屜式的側欄,便簡單上網找了找,目前瞭解到的可以通過MMDrawerController和SWRevealViewController這兩個第三方的frameworks做出抽屜式側欄的效果。這兩個frameworks都可以在Github上搜到,有興趣的同學都可以看看。我在專案中用的是MMDrawerController,至於為什麼,原因很簡單,因為MMDrawerController的star比較多。。。所以這篇文章也是記錄一下我使用MMDrawerController的過程和問題。
新建專案
新建一個名叫MMDrawerControllerDemo的專案,language選擇Swift,storyboard示意圖如下,具體過程就不寫了,中間是一個Button,將起始頁面的title改為Home,也就是主頁。
新建一個檔案,選擇cocoa touch class,命名為SecondViewController
在storyboard中選擇右邊的ViewController,在identity inspector中將其class設定為SecondViewController,同時設定一個storyboard ID
匯入MMDrawerController
因為方便在專案中使用,我是使用了cocoapods,至於如何使用cocoapods,不會的同學就自行百度一下吧,這種小問題還不需要Google出馬。
建立側欄
新建一個檔案,同樣是選擇cocoa touch class,命名為LeftDrawerViewController。
其實可以同時在主頁的左右兩邊各新增一個側欄,但是我這裡僅僅是在左側新增。
接下來,在viewDidLoad()方法之前加上:
var tableView: UITableView!
在viewDidLoad()方法的最後加上:
tableView = UITableView(frame: CGRectZero, style: .Plain)
tableView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height)
tableView.delegate = self
tableView.dataSource = self
view.addSubview(tableView)
tableView.registerNib(UINib(nibName: "LeftDrawerTableViewCell", bundle: nil), forCellReuseIdentifier: "LeftDrawerTableViewCell")
在class的外部加上以下程式碼:
// MARK: - table view delegate, table view datasource
extension LeftDrawerViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("LeftDrawerTableViewCell", forIndexPath: indexPath) as! LeftDrawerTableViewCell
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
}
其中的LeftDrawerTableViewCell是我新建的一個繼承自UITableViewCell的Swift檔案,關於UITableView具體的這裡就不講了,不是重點,如果不會的就自行百度或者Google吧。
使用MMDrawerController
之前已經通過cocoapods匯入了MMDrawerController,現在就開始使用MMDrawerController。
開啟AppDelegate.swift
在didFinishLaunchingWithOptions方法的上方新增以下程式碼:
var centerContainer: MMDrawerController!
這時候Xcode會報一個警告,`Use of undeclared type MMDrawerController`
因為是從cocoapods匯入的,所以需要在class上方新增
import MMDrawerController
但是這時候Xcode又會報一個警告,`No such module MMDrawerController`
對於這個問題的解決辦法,我是新建了一個名為MMDrawerControllerDemo-Bridge-Header.h的header檔案,新增以下程式碼即可:
#import <MMDrawerController/MMDrawerController.h>
然後在Build Settings中找到Objective-C Bridging Header這一項,寫上MMDrawerControllerDemo-Bridge-Header.h這個檔案在本專案中的路徑,這樣一來,專案就可以正常執行了,但是為什麼需要這個檔案,我目前還不是很清楚。
繼續回到AppDelegate.swift這個檔案
在didFinishLaunchingWithOptions方法中新增以下程式碼:
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let centerViewController = mainStoryboard.instantiateViewControllerWithIdentifier("HomePageViewController") as! ViewController
let leftDrawerViewController = LeftDrawerViewController()
let centerNav = UINavigationController(rootViewController: centerViewController)
centerContainer = MMDrawerController(centerViewController: centerNav, leftDrawerViewController: leftDrawerViewController)
centerContainer.openDrawerGestureModeMask = .PanningCenterView
centerContainer.closeDrawerGestureModeMask = .PanningCenterView
window?.rootViewController = centerContainer
window?.makeKeyAndVisible()
現在可以將專案執行起來看下效果了。
新增子頁面
返回到storyboard,在專案的一開始,我建立了一個名叫SecondViewController的ViewController。
選擇“下一頁”按鈕,control+drag到SecondViewController,選擇push
這時候再次執行程式,進入到第二個頁面之後,會發現在第二個頁面同樣能夠顯示出側欄,但是一般來說,應該只有主頁能夠顯示出側欄。
現在我講一下我選擇的方法來解決這個問題。
回到AppDelegate.swift
將以下兩行程式碼註釋,如果你想刪了也隨意:
centerContainer.openDrawerGestureModeMask = .PanningCenterView
centerContainer.closeDrawerGestureModeMask = .PanningCenterView
開啟ViewController.swift
在viewDidLoad()之後加入以下程式碼:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let appDelegte = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegte.centerContainer.openDrawerGestureModeMask = .PanningCenterView
appDelegte.centerContainer.closeDrawerGestureModeMask = .PanningCenterView
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
let appDelegte = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegte.centerContainer.openDrawerGestureModeMask = .None
appDelegte.centerContainer.closeDrawerGestureModeMask = .None
}
現在看下執行效果就正常了。
新增BarButtonItems
繼續在ViewController.swift,新增以下程式碼:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "menu.png"), style: .Plain, target: self, action: "sideMenuTapped:")
}
func sideMenuTapped(sender: UIBarButtonItem) {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
}
到此這個demo就完成了,demo地址Github