iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
自我挑戰組

來寫看看app好了! Swift探索之旅系列 第 7

Day#07 新增(2)

前言

接續著前一天沒做完的新增功能,今天繼續接著做~邊做也一邊介紹用到的方法與程式碼。

Storyboard

我們再次回到storyboard,從畫面右上角的選項進入連結controller的地方,然後選擇相對應的classentryViewController
在這個畫面中,我們希望可以顯示欲新增的to-do的內容與時間,因此需要新增一些UI元件。

entryViewController

除此之外,為了方便起見,我們可以在同一個畫面指定一個storyboard Id,在這邊我們打上enter,到時候可以在程式面去連結。

storyboard id不能重複

接著找到TextField,用來顯示todo的標題,或稱作內容。找到後也是一樣,直接拖移到剛剛選擇的畫面當中。

然後設定constraints,包含margin(上左右分別為0)、以及height(20...50,隨便XD)

剛剛還提到了要有一個日期,因此我們點右上角新增,然後搜尋UIDatePicker,拖拉至畫面中。同樣的,設定constraints,在這邊我設定上50、下左右為0。可得到下圖的畫面。

昨天提到outlet是程式中有宣告的元件,因此我們將UIDatePicker加上程式的對應變數,如下。

ViewController

好了,畫面元件的部分應該就到此為止。我們來把還沒寫完的程式部分補齊。
主畫面上面,已經新增了右上角的加號 :heavy_plus_sign: ,不過按下按鈕後做什麼行為我們還沒定義。

didTapAddButton

還記得幾天前我們解析過新的寫法guard let其實可以就理解成if let
因此這邊使用方法instantiateViewController,利用我們剛剛指定的identifier="enter"去建立出一個新的storyboard相對應的controller。

@IBAction func didTapAddButton() {
    guard let vc = storyboard?.instantiateViewController(withIdentifier: "enter") as? EntryViewController else {
        return
    }

    vc.title = "New Item"
    vc.navigationItem.largeTitleDisplayMode = .never
    navigationController?.pushViewController(vc, animated: true)
}

navigationController就像是一個容器,裡面可以用來放置及疊放各個頁面,畫面上方預設會有一個導覽列( Navigation Bar ) ,其中可以放置標題及按鈕,來切換或退出頁面,像是內建的 設定 App 就是一個例子。
因此,方法pushViewController就是把新的頁面push到當下的stack中。

refresh

當我們新增完一個新項目之後,我們希望畫面可以重撈資料、並將所有的東西放到tableView裡,當然,包含新項目。

首先,在這個畫面,我們先嘗試與資料庫連線。

private let realm = try! Realm()

didTapAddButton

接著,在didTapAddButton新增一個handler,然後就是讓我頭痛了好久的...

vc.completionHandler = { [weak self] in
    self?.refresh()
}

weak
In Swift, we need to use weak self and unowned self to give ARC *(Automatic Reference Counting,協助我們管理memory以及reference)* the required information between relationships in our code. Without using weak or unowned you’re basically telling ARC that a certain “strong reference” is needed and you’re preventing the reference count from going to zero. **Without correctly using these keywords we possibly retain memory which can cause memory leaks in your app.** So-called Strong Reference Cycles or Retain Cycles can occur as well if weak and unowned are not used correctly.^2^

雖說大致理解weak的用途與目的,不過何時使用、如何使用,看越多資料,就會發現有越多無法理解的專有名詞 (´−`) ンー崩潰

誠摯希望有善心人士可以協助解釋,或是分享你曾看過好懂的解說文

viewDidLoad

當畫面load進memory時,我們將資料庫的資料mapping到我們宣告的物件

data = realm.objects(TodoListItem.self).map({$0})

refresh

因應剛剛提到的reload資料,我們新增一個refresh如下

func refresh() {
    data = realm.objects(TodoListItem.self).map({$0})
    table.reloadData()
}

結語

然後就可以跑了!
接下來做新增的按鈕,笑死打完發現不能新增 (~ ̄▽ ̄)~

參考資源

  1. 導覽控制器 UINavigationController
  2. Weak self and unowned self explained in Swift
  3. instantiateViewController(withIdentifier:)

上一篇
Day#06 新增
下一篇
Day#08 查看、刪除
系列文
來寫看看app好了! Swift探索之旅30

尚未有邦友留言

立即登入留言