今天是实训第四天,第二个Demo —— Checklists,依然在进行中,预计本周末前可以完成。
为了方便起见,以后我都把Checklists简称为CL吧。重新解释一下什么是CL:是一个日程管理,一个活动记录表。
上面有每天需要做的项目,完成时可以打勾,也就是 todo-list。可以理解为21天养成一个好习惯,或诚信状,或日常打卡。
由于上午考毛概,因此今天的工作从下午开始。概括来说主要进行了如下工作:
1. 熟悉iOS的MVC模式,创建data模型
2. 代码重构,clean up
3. 引入Array,创建CLItem类
4. 加入navigation
1. 关于MVC模式:
Data Model是Row,每条Row都是实在的数据。
View Controller在这里是UITableViewController。
View是一个视图集合,可以看作一棵树。其根节点是UITableView(主View),沿根往下的子View是UITableViewCell,UIView,UILabel...
工作时,table view controller作为数据源,从data model处取得data(也就是Row),然后put到UITableView的Cells中。
正如我昨天所说的,Cell只起到容器的作用,真正的data是Row对应的内容。
2.关于代码重构:
代码重构是周期性进行的。及时 Clean Up 有助于提高代码的可读性。
可以看到,我在init method中创建了数据模型。所有item的添加只需要修改init函数。
因为空变量在Swift语言中是一个big no-no(禁忌之事),所以每个item都要进行初始化。
// init method
// during app startup, the init method is called.
required init?(coder aDecoder: NSCoder) {
// items = [ChecklistItem()] //declare the array obj()
items = [ChecklistItem]()
let row0item = ChecklistItem() // create an obj
row0item.text = "Waiking the 00" // set properties
row0item.checked = false // set properties
items.append(row0item) // append to the array
let row1item = ChecklistItem()
row1item.text = "Waiking the 01"
row1item.checked = false
items.append(row1item)
// your data model is -> items
super.init(coder: aDecoder)
}
至于重写的tableView方法,也比昨天简单了许多,这主要是因为我后面引入了item数组。
新增的 configureCheckmark 和 configureText ,则是针对 item 对象进行配置text和checked属性的两个方法。
// two data source protocol
// the data source is the link between your data and the table view.
// find how many rows there are.
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return items.count
}
// ask the data source for a cell.
override func tableView(_ tableView:UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// indexPath is an obj that points to a specific row in the table.
let cell = tableView.dequeueReusableCell(
withIdentifier: "ChecklistItem", for: indexPath)
let item = items[indexPath.row]
configureCheckmark(for: cell, with: item) // new methodr
configureText(for: cell, with: item)
return cell // to obtain the cell for that row
}
3.关于引入Array:
新建一个Swift文件:ChecklistItem.swift,用来建立类,赋予text 和 checked 两个属性。这是面向对象的方法,也可以看作C++中的结构体。
类中的 toggleChecked 方法是用来触发勾选的。
import Foundation
class ChecklistItem {
var text = ""
var checked = false
func toggleChecked() {
checked = !checked
}
}
其实触发勾选存在一个同步和异步的问题。
早先发现:
因为故事版中的 check 都默认是勾选的, 而 model 代码中的 check 默认是 false(不选),所以 run 时发现勾选要点击2下才会消失。
这是因为 data model 和 view 是 out of sync。
优化代码后,在return cell之前先 configureCheckmark 一下,可以把真实的check状态传递给cell。
这样App在start up后显示的就是 data model 中的check状态了。
4.关于加入导航条:
接下来要做的事情,按IOS学徒的作者来说就是:
• Add a navigation controller
• Put the Add button into the navigation bar
• Add a fake item to the list when you press the Add button
• Delete items with swipe-to-delete
• Open the Add Item screen that lets the user type the text for the item
在Xcode的Editor中可以选择内嵌一个Navigation Controller。并可以对navigation进行改名。
同时,从obj图书馆中可以拖入bar button item。
这里仅仅起了个头,更具体的工作留给明天写吧!
遗留问题:declare Array对象时,以下两种声明都是正确的,但是突然想不通为什么小括号可以加在中括号内了。
// items = [ChecklistItem()] //declare the array obj()
items = [ChecklistItem]()