接著昨天的內容,今天來開發Swift的部分,為了一同練習不一樣的開發方式,所以這邊就算有用到相同的物件,我也會盡量用不同的方式呈現或是增加一點小變化
預計是使用者更換完日期後,帶出該天的資料,但每次變動就搜尋一次資料庫,可能不是好方法,在使用者快速更換日期的時候也有可能出現錯亂,因此我刻意在UIDatePicker上增加一個「完成」按鈕,只要選定好後按下,就可更換日期,畫面如下
程式碼部分,先把變數都命名出來
let sqlManager = (UIApplication.shared.delegate as! AppDelegate).sqlManager
@IBOutlet weak var dateText: UITextField!
let datePicker = UIDatePicker() // Date的DatePicker
let showDateFormatter = DateFormatter() // 要顯示出來看的日期格式
let dateFormatter = DateFormatter()
再在viewDidLoad()中加入設定,然後因為我們要新增按鈕來觸發事件,因此這裡就不用針對datePicker的changevalue設定action囉
// 設置時間顯示的格式
showDateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.dateFormat = "yyyyMMdd"
// 設置 UIDatePicker 格式
datePicker.datePickerMode = .date
// 設置顯示的語言環境
datePicker.locale = Locale(identifier: "zh_TW")
dateText.inputView = datePicker
這邊另外寫下要放在UIDatePicker上面的一行UIToolBar,含有Done功能的UIButton
// 新建tool bar
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.sizeToFit()
// 新建UIButton,顯示Done字樣,觸發changeDate事件
let doneButton = UIButton()
doneButton.setTitle("Done", for: UIControlState.normal)
doneButton.setTitleColor(UIColor.init(red: 0/255, green: 122/255, blue: 255/255, alpha: 1), for: UIControlState.normal)
doneButton.addTarget(self, action: #selector(changeDate), for: .touchUpInside)
// 新建一個空白的按鈕UIBarButtonItem,只適用在排版而已,所以也沒有任何的文字、功能
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
// 將兩個按鈕加入tool bar,因為只能加入UIBarButtonItem,因此要將UIButton轉型
toolBar.setItems([spaceButton, UIBarButtonItem(customView: doneButton)], animated: false)
toolBar.isUserInteractionEnabled = true
// 設定tool bar給UITextField
dateText.inputAccessoryView = toolBar
再來加入changeDate功能,先簡單寫下目前的作用,後面還要加上查詢資料庫跟畫面呈現的部分
@objc func changeDate() {
dateText.text = showDateFormatter.string(from: datePicker.date)
view.endEditing(true)
}
這樣就可以呈現上方圖片內的內容囉
再來我們先處理Note的部分,一樣先拖拉出Outlet
@IBOutlet weak var noteText: UITextView!
再來要加入完成事件,也就是當我們編輯修改完欄位之後,要將新的內容存入資料庫,不過TextView要觸發事件需要加入協定UITextViewDelegate
class DayViewController: UIViewController, UITextViewDelegate {
還要將delegate指定對象(在viewDidLoad()裡面)
noteText.delegate = self
之後就可以利用textViewDidEndEditing功能來處理了
func textViewDidEndEditing(_ textView: UITextView) {
sqlManager.updateDayNoteById(id: dateFormatter.string(from: datePicker.date), note: noteText.text)
}
SQLiteManager.swift裡面update的功能
func updateDayNoteById(id: String, note: String?) {
do {
let item = TB_DAY.filter(TB_DAY_WORK_ID == id)
if try database.run(item.update(TB_DAY_NOTE <- note)) > 0 {
print("update day")
}
} catch {
}
}
不過,因為之後會有用TableView,我發現我們在storyboard中那樣加入tap gesture recognize會導致cell無法被觸發,因此我這邊也調整一下寫法,在一進入畫面的時候就新增,這樣其他物件應該是會被疊在這個單點觸及的物件上方,就不會導致因為覆蓋堆疊而沒有反應了
在viewDidLoad()一進來的地方加入程式碼(記得把Main.storyboard Day Scene中的Tap Gesture Recognize刪掉喔)
// 增加一個觸控事件
let tap = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
tap.cancelsTouchesInView = false
// 加在最基底的 self.view 上
self.view.addGestureRecognizer(tap)
最後加上hideKeyboard功能,就完成啦
@objc func hideKeyboard(){
// 除了使用 self.view.endEditing(true),也可以用 resignFirstResponder(),來針對一個元件隱藏鍵盤
self.view.resignFirstResponder()
}