iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
Mobile Development

少年K的Swift奇幻漂流記系列 第 15

Day15 Swift MessageBoard App 實作 Part3

  • 分享至 

  • xImage
  •  

元件動作

送出按鈕

先來看送出按鈕,裡面還有關於排序的部分

// 送出按鈕
@IBAction func btnSentAciton(_ sender: Any) {

    // 使用Realm套件
    let realm = try! Realm()

    // 判斷是否為送出按鈕
    if btnSent.currentTitle == "送出" {

        if let user = txfUser.text, let message = txvContent.text {

            // 確認有輸入使用者名稱和留言內容
            if !user.isEmpty && !message.isEmpty {

                // 抓取送出留言的時間
                let currentTime = getSystemTime()

                // 將內容存為MessageBoard格式
                let newMessage = MessageBoard(name: user, content: message, currentTime: currentTime)

                // 寫入Realm資料庫
                try! realm.write {
                    realm.add(newMessage)

                    // 如果isAscending是true(升序),就加到陣列的最後面,就是由舊到新的概念
                    if isAscending {
                        messageArray.append(newMessage)

                    // 如果是false(由新到舊),就放到陣列的最前面
                    } else {
                        messageArray.insert(newMessage, at: 0) // 直接把值插入到row的第一個位置
                    }

                    // 刷新
                    tbvTest.reloadData()

                    // 送出完成之後,將使用者名稱和內容變為空白
                    txfUser.text = ""
                    txvContent.text = ""
                }
                print("Added new message with time: \(currentTime)") // 這行是用來確定時間有被設定到
            } else {
                showAlert(message: "請輸入使用者名稱和內容") // 如果沒有輸入訊息,會跳出來叫使用者重新填
            }
        }
    }
}

在送出按鈕內有一個得到系統時間的function,方便後面我們進行排序

// 抓取系統時間
func getSystemTime() -> String {
    let currentDate = Date()
    let dateFormatter: DateFormatter = DateFormatter()

    // 設定格式
    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    dateFormatter.locale = Locale.ReferenceType.system
    dateFormatter.timeZone = TimeZone.ReferenceType.system
    return dateFormatter.string(from: currentDate)
}

再來看排序按鈕

@IBAction func btnSortSection(_ sender: Any) {
    showSortOptions()
}

showSortOptions寫法

// 排序按鈕的function
func showSortOptions() {

    // 命名一個空的警告彈窗
    let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

    // 升序選項
    let ascendingAction = UIAlertAction(title: "時間升序", style: .default) { [weak self] _ in

        // 改變追蹤排序的變數
        self?.isAscending = true

        // 利用前面改變的追蹤的變數做排序
        self?.sortMessages()

        // 刷新頁面
        self?.tbvTest.reloadData()
    }

    // 降序選項
    let descendingAction = UIAlertAction(title: "時間降序", style: .default) { [weak self] _ in

        // 改變追蹤排序的變數
        self?.isAscending = false

        // 利用前面改變的追蹤的變數做排序
        self?.sortMessages()

        // 刷新頁面
        self?.tbvTest.reloadData()
    }

    // 取消選項
    let cancelAction = UIAlertAction(title: "取消", style: .cancel, handler: nil)

    // 將上面的選項加入最開始命名的空的警告彈窗
    alertController.addAction(ascendingAction)
    alertController.addAction(descendingAction)
    alertController.addAction(cancelAction)

    // 這裡是設定彈出視窗是要從排序按鈕按才會彈出來
    if let popoverController = alertController.popoverPresentationController {
        popoverController.sourceView = btnSort
        popoverController.sourceRect = btnSort.bounds
    }

    // 呼叫出alerController
    present(alertController, animated: true, completion: nil)
}

showSortOptions內使用到的sortMessages()

// 排序
func sortMessages() {

    // 閉包寫法
    messageArray.sort { (messages1, messages2) -> Bool in

        //如果是升序就由小排到大,不是的話就由大排到小
        if isAscending {
            return messages1.currentTime < messages2.currentTime
        } else {
            return messages1.currentTime > messages2.currentTime
        }
    }
}

最後補充

前面有設定到tableView,所以後來有在viewDidLoad裡面加上setUI()的function,但這篇除了用到tableView,還要用到我們自己寫的Model,所以要額外寫一個dataBase的function

dataBase

func dataBase() {
    let realm = try! Realm()
    let messageBoards = realm.objects(MessageBoard.self)
    messageArray = Array(messageBoards)
    sortMessages()
    tbvTest.reloadData()
    print("file :a \(realm.configuration.fileURL!)")
}

包進viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    setUI()
    dataBase()
}

結論

大家看過我在程式裡的註解和我在創建這個專案時的步驟之後有沒有更了解元件動作該做什麼了呢~明天會講解tableView的左滑刪除和右滑編輯功能喔!


上一篇
Day14 Swift MessageBoard APP 實作 Part2
下一篇
Day16 Swift MessageBoard App 實作 Part 4:TableView 左滑
系列文
少年K的Swift奇幻漂流記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言