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:)

<<:  易用性、无障碍、通用、包容性设计 — part2

>>:  [从0到1] C#小乳牛 练成基础程序逻辑 Day 7 - 程序码收纳术 3种注解

从零开始学3D游戏设计:基础粒子效果

这是 Roblox 从零开始系列,在效果章节的单元,今天你将学会如何透过粒子发射器来做出基本的粒子特...

Day29. Blue Prism斜杠好帮手 -BP自动收集股价

经济不景气一份稳定的工作, 相对收入也是稳如鸡肋一般(吃不饱、饿不死), 一想到侄子最近在抱怨刚进入...

探讨 Simple Factory, Abstract Factory and Factory 的差异

刚学完三大工厂的模式,那它们之间的差异性究竟是什麽呢? 学习目标: 探讨简单工厂、抽象工厂、工厂的差...

[Day09] TS:什麽!型别也有分配律?理解 Extract 和 Exclude 的实作

上面这个是今天会提到的内容,如果你已经可以轻松看懂,欢迎直接左转去看我同事的精彩文章 — 「Fro...

Day07,搭配gitlab-ci执行image auto build

正文 今天要设定gitlab上的专案,让他们能够在git commit时自动打包成docker im...