iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 19
1
Software Development

iOS 三十天上架記帳 APP系列 第 19

Money Mom - 實做收支記錄的界面 Part 2

前面我們做好基本的界面,讓使用者可以從「快速記帳首頁」跳轉到「新增收支記錄」的界面,並為了調整 Core Data Model 的結構又寫了 Migration 程式,終於我們可以繼續完成後續功能:

  1. 將收支記錄儲存
  2. 加入 UITabBarController
  3. 設計收支記錄首頁的 UITableView(下一篇)

儲存收支記錄

前面我們已經做好了新增「收支記錄」的界面,也就是使用者將快速記帳轉換成詳細收支記錄的界面,當使用者按下儲存時,我們會將這筆「收支記錄」儲存起來,並標記對應的「快速記帳」為已處理,如下:

override func save() {
    guard let quickRecord = quickRecord else {
        return
    }

    let viewContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer!.viewContext

    guard let transaction = NSEntityDescription.insertNewObject(forEntityName: String(describing: Transaction.self), into: viewContext) as? Transaction else {
        fatalError("Insert Transaction Failed")
    }

    quickRecord.isProcessed = true
    quickRecord.transaction = transaction

    transaction.amount = quickRecord.amount
    transaction.audioUUID = quickRecord.audioUUID
    transaction.createdAt = datePicker.date
    transaction.id = UUID()
    transaction.location = locationTextField.text ?? ""
    transaction.tags = quickRecord.tags
    if transactionTypeSegmentedControl.selectedSegmentIndex == 0 {
        transaction.type = TransactionType.INCOME
    } else {
        transaction.type = TransactionType.EXPENSE
    }
    transaction.quickRecord = quickRecord

    try! viewContext.save()

    navigationController?.popToRootViewController(animated: true)
}

加入 UITabBarController

前段我們儲存資料後,最後我們會用 UINavigationController 的 popToRootViewController 回到首頁,但是以前面所規劃的使用流程來說,我們應該要回到「收支記錄」的首頁:

此時我們就可以利用 UITabBarController 來調整我們的動線。

更換 window 的 rootViewController 為 UITabBarController

let rootViewController = UITabBarController()
rootViewController.viewControllers = [
    UINavigationController(rootViewController: HomeViewController()),
    UINavigationController(rootViewController: TransactionHomeViewController())
]
window?.rootViewController = rootViewController

請 UITabBarController 協助切換到可以處理「編輯快速記帳」的界面

我們在快速記帳首頁,往右滑動點擊編輯時,會進入新增收支記錄的界面,新增收支記錄的界面是在另一個動線上,如下圖:

使用者從「快速記帳首頁」跳到「新增收支記錄」的界面,其實是從某一個 UINavigationController 跳到另外一個 UINavigationController,當然如果要直接請 UITabBarController 跳到該頁面也可以,但是我們應該要用「Protocol 先行」的做法,讓彼此之間的關聯不要這麼「強烈」。

使用者右滑時,我們應該要從 UITabBarController 中,找到懂得「如何新增收支記錄」的界面,如下:

protocol UnderstandHowToCreateTransaction {
    func userWannaCreateTransactionFrom(quickRecord: QuickRecord)
}

任何實做這個 Protocol 的 ViewController,都知道該如何處理這樣的需求,因此我們的「收支記錄首頁」和「新增收支記錄」的界面都要實做這個 Protocol,如下:

extension TransactionHomeViewController: UnderstandHowToCreateTransaction {
    func userWannaCreateTransactionFrom(quickRecord: QuickRecord) {
        navigationController?.pushViewController(CreateTransactionViewController(quickRecord: quickRecord), animated: true)
    }
}
extension CreateTransactionViewController: UnderstandHowToCreateTransaction {
    func userWannaCreateTransactionFrom(quickRecord: QuickRecord) {
        self.quickRecord = quickRecord
    }
}

如此一來,在快速記帳首頁想要請 UITabBarController 切換頁面變得相當容易,而且又不會造成關聯性太高,如下:

func userWannaEdit(quickRecord: QuickRecord) {
    if let viewController = tabBarController?.viewControllers?.first(where: { controller in
        return (controller as? UINavigationController)?.topViewController is UnderstandHowToCreateTransaction
    }) {
        tabBarController?.selectedViewController = viewController
        ((viewController as! UINavigationController).topViewController as! UnderstandHowToCreateTransaction).userWannaCreateTransactionFrom(quickRecord: quickRecord)
    }
}

備註:如果硬要說的話,「快速記帳首頁」也「知道如何處理新增收支記錄的需求」,而其處理的方式就是「找出 UITabBarController 中會處理的界面」。最初設計這個 Protocol 就是針對 UITabBarController,因此如果是上述遞迴狀況,我們就要「適當地」停止,不要讓每個界面都去實做這個 Protocol。

展示

程式碼:GitHub

在畫面中,使用者從「快速記帳首頁」點編輯後,會先跳到「收支記錄」的分頁,然後再跳到其中的「新增收支記錄」界面。

目前暫時把「收支記錄首頁」做得跟「快速記帳首頁」一樣,下一篇會專門處理收支記錄首頁的界面。


上一篇
Money Mom - 實做新增收支記錄的界面 Part 1.5
下一篇
Money Mom - 實做收支記錄的界面 Part ∞
系列文
iOS 三十天上架記帳 APP30

尚未有邦友留言

立即登入留言