iT邦幫忙

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

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

Money Mom - 實做新增收支記錄的界面 Part 1

Money Mom 目前只能記錄「快速記帳」,但是每筆記帳除了金額、標籤以外,還有其它很重要的資訊,像是「時間」、「地點」、「消費類型(收、支)」,因此我們需要實做這個界面來整理快速記帳。

新增記錄的界面,預計會有跟快速記帳一模一樣的欄位,再加上「時間」、「地點」、「消費類型」這三個欄位。

重複利用快速記帳的元件

因為新增收支記錄時,還是需要「金額」、「標籤」、「錄音」這三個欄位,只是要再多加上「時間」、「地點」、「消費類型」。

有一個方法是直接複製快速記帳的程式碼,但是身為一個工程師,我們應該無時無刻警惕自己,減少使用 cmd+c 和 cmd+v 的次數。

所以最後我選擇另外一個方法:繼承。

我們可以透過繼承 QuickCreateViewController(快速記帳),再透過 override 新增新的界面元件、排版,就可以有效減少重複的程式碼,如果未來有調整快速記帳頁面的元件時,也可以同步更新這個界面,如下:

class CreateRecordViewController: QuickCreateViewController {
    var quickRecord: QuickRecord? {
        didSet {
            if let quickRecord = quickRecord {
                updateUI(with: quickRecord)
            }
        }
    }

    convenience init(quickRecord: QuickRecord) {
        self.init()

        self.quickRecord = quickRecord
        updateUI(with: quickRecord)
    }

    private func updateUI(with quickRecord: QuickRecord) {
        amountTextField.text = quickRecord.amount
        tags = quickRecord.tags
        tagCollectionView.reloadData()
    }
}

加入選擇時間的元件

就如一開始規劃的方式,選擇時間我們可以用一個 UITextField,然後把 inputView 換成 UIDatePicker,如下:

let datePicker: UIDatePicker = {
    let datePicker = UIDatePicker()
    datePicker.datePickerMode = .dateAndTime
    datePicker.addTarget(self, action: #selector(datePickerValueChanged), for: .valueChanged)
    return datePicker
}()

lazy var dateTextField: UITextField = {
    let dateTextField = UITextField()
    dateTextField.inputView = datePicker
    dateTextField.textColor = MMColor.black
    dateTextField.leftViewMode = .always
    dateTextField.leftView = {
        let leftViewLabel = UILabel()
        leftViewLabel.text = "日期:"
        leftViewLabel.sizeToFit()
        leftViewLabel.textColor = MMColor.black
        return leftViewLabel
    }()
    return dateTextField
}()

@objc func datePickerValueChanged() {
    setDateTextFieldText(with: datePicker.date)
}

private func setDateTextFieldText(with date: Date) {
    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    formatter.timeStyle = .short
    formatter.timeZone = TimeZone.current
    dateTextField.text = formatter.string(from: date)
}

加入選擇地點的元件

理想的設計,應該是在新增快速記帳時,就先把使用者當下的位置記錄下來,然後新增收支記錄時,就可以預先顯示當時的位置,使用者要編輯的時候,會跳出以該點為中心的地圖,讓使用者選擇地點(也可以透過搜尋店家名稱的方式),在此先用一個簡單的 UITextField 代替,之後再接入 Google Map。

lazy var locationTextField: UITextField = {
    let locationTextField = UITextField()
    locationTextField.textColor = MMColor.black
    locationTextField.leftViewMode = .always
    locationTextField.leftView = {
        let leftViewLabel = UILabel()
        leftViewLabel.text = "地點:"
        leftViewLabel.sizeToFit()
        leftViewLabel.textColor = MMColor.black
        return leftViewLabel
    }()
    return locationTextField
}()

加入選擇消費分類(收、支)的元件

前面規劃時以為只有 UISwitch,本來要自己做兩個按鈕取代 UISwitch,結果後來發現還有 UISegmentedControl 可以用,Apple 好貼心啊!

lazy var transactionTypeSegmentedControl: UISegmentedControl = {
    let transactionTypeSegmentedControl = UISegmentedControl()
    transactionTypeSegmentedControl.tintColor = MMColor.black
    transactionTypeSegmentedControl.insertSegment(withTitle: "收入", at: 0, animated: false)
    transactionTypeSegmentedControl.insertSegment(withTitle: "支出", at: 1, animated: false)
    transactionTypeSegmentedControl.addTarget(self, action: #selector(transactionTypeChanged), for: .valueChanged)

    return transactionTypeSegmentedControl
}()

@objc func transactionTypeChanged() {
    if transactionTypeSegmentedControl.selectedSegmentIndex == 0 {
        transactionTypeSegmentedControl.tintColor = MMColor.green
        transactionTypeSegmentedControl.setTitleTextAttributes([
            NSAttributedStringKey.foregroundColor: MMColor.black
        ], for: .normal)
        transactionTypeSegmentedControl.setTitleTextAttributes([
            NSAttributedStringKey.foregroundColor: MMColor.black
        ], for: .selected)
    } else {
        transactionTypeSegmentedControl.tintColor = MMColor.red
        transactionTypeSegmentedControl.setTitleTextAttributes([
            NSAttributedStringKey.foregroundColor: MMColor.black
        ], for: .normal)
        transactionTypeSegmentedControl.setTitleTextAttributes([
            NSAttributedStringKey.foregroundColor: MMColor.white
        ], for: .selected)
    }
}

這個顏色、排版……「界面重構」的優先度越來越高了。

展示

程式碼如下(GitHub):

  1. 新增日期輸入框
  2. 新增地點輸入框
  3. 新增消費分類選擇

下一篇會專心處理 Core Data 的功能,使用者按下右上角儲存後,原本的快速記帳記錄會被設定為「已整理」,然後新的收支記錄會被儲存起來。


上一篇
Money Mom - 客製化 UITableViewCell 滑動之背景按鈕
下一篇
Money Mom - 實做新增收支記錄的界面 Part 1.5
系列文
iOS 三十天上架記帳 APP30

尚未有邦友留言

立即登入留言