iOS實現簡單的抽屜式側欄——MMDrawerController的使用

afishhhhh發表於2016-03-07

在最近的一個專案中需要製作一個抽屜式的側欄,便簡單上網找了找,目前瞭解到的可以通過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

相關文章