鍍金池/ 教程/ iOS/ 最后的潤色
開始
裝飾者模式 - Decorator
單例模式 - Singleton
外觀模式 - Facade
觀察者模式 - Observer
準備工作
iOS 設計模式
適配器模式 - Adapter
備忘錄模式 - Memento
最后的潤色
小結
設計模式之王- MVC

最后的潤色

現(xiàn)在我們將添加最后一個功能:允許用戶刪除專輯,以及撤銷上次的刪除操作。

ViewController 里添加如下屬性:

// 為了實現(xiàn)撤銷功能,我們用數(shù)組作為一個棧來 push 和 pop 用戶的操作
var undoStack: [(Album, Int)] = []

然后在 viewDidLoadreloadScroller() 后面添加如下代碼:

let undoButton = UIBarButtonItem(barButtonSystemItem: .Undo, target: self, action:"undoAction")
undoButton.enabled = false;
let space = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target:nil, action:nil)
let trashButton = UIBarButtonItem(barButtonSystemItem: .Trash, target:self, action:"deleteAlbum")
let toolbarButtonItems = [undoButton, space, trashButton]
toolbar.setItems(toolbarButtonItems, animated: true)

上面的代碼創(chuàng)建了一個 toolbar ,上面有兩個按鈕,在 undoStack 為空的情況下, undo 的按鈕是不可用的。注意 toolbar 已經(jīng)在 storyboard 里了,我們需要做的只是配置上面的按鈕。

我們需要在 ViewController.swift 里添加三個方法,用來處理專輯的編輯事件:增加,刪除,撤銷。

先寫添加的方法:

func addAlbumAtIndex(album: Album,index: Int) {
    LibraryAPI.sharedInstance.addAlbum(album, index: index)
    currentAlbumIndex = index
    reloadScroller()
}

做了三件事:添加專輯,設為當前的索引,重新加載滾動條。

接下來是刪除方法:

func deleteAlbum() {
    //1
    var deletedAlbum : Album = allAlbums[currentAlbumIndex]
    //2
    var undoAction = (deletedAlbum, currentAlbumIndex)
    undoStack.insert(undoAction, atIndex: 0)
    //3
    LibraryAPI.sharedInstance.deleteAlbum(currentAlbumIndex)
    reloadScroller()
    //4
    let barButtonItems = toolbar.items as [UIBarButtonItem]
    var undoButton : UIBarButtonItem = barButtonItems[0]
    undoButton.enabled = true
    //5
    if (allAlbums.count == 0) {
        var trashButton : UIBarButtonItem = barButtonItems[2]
        trashButton.enabled = false
    }
}

挨個看一下各個部分:

  • 獲取要刪除的專輯。
  • 創(chuàng)建一個 undoAction 對象,用元組存儲 Album 對象和它的索引值。然后把這個元組加到了棧里。
  • 使用 LibraryAPI 刪除專輯數(shù)據(jù),然后重新加載滾動條。
  • 既然撤銷棧里已經(jīng)有了數(shù)據(jù),那么我們需要設置撤銷按鈕為可用。
  • 檢查一下是不是還剩專輯,如果沒有專輯了那就設置刪除按鈕為不可用。

最后添加撤銷按鈕:

func undoAction() {
    let barButtonItems = toolbar.items as [UIBarButtonItem]
    //1       
    if undoStack.count > 0 {
        let (deletedAlbum, index) = undoStack.removeAtIndex(0)
        addAlbumAtIndex(deletedAlbum, index: index)
    }
    //2       
    if undoStack.count == 0 {
        var undoButton : UIBarButtonItem = barButtonItems[0]
        undoButton.enabled = false
    }
    //3       
    let trashButton : UIBarButtonItem = barButtonItems[2]
    trashButton.enabled = true
}

照著備注的三個步驟再看一下撤銷方法里的代碼:

  • 首先從棧里 pop 出一個對象,這個對象就是我們當初塞進去的元祖,存有刪除的 Album 對象和它的索引位置。然后我們把取出來的對象放回了數(shù)據(jù)源里。
  • 因為我們從棧里刪除了一個對象,所以需要檢查一下看看棧是不是空了。如果空了那就設置撤銷按鈕不可用。
  • 既然我們已經(jīng)撤消了一個專輯,那刪除按鈕肯定是可用的。所以把它設置為 enabled 。

這時再運行應用,試試刪除和插銷功能,似乎一切正常了:

http://wiki.jikexueyuan.com/project/ios-design-patterns-in-swift/images/13.png" alt="" />

我們也可以趁機測試一下,看看是否及時存儲了專輯數(shù)據(jù)的變化。比如刪除一個專輯,然后切到后臺,強關應用,再重新開啟,看看是不是刪除操作成功保存了。

如果想要恢復所有數(shù)據(jù),刪除應用然后重新安裝即可。