
這個(gè)教程涉及以下內(nèi)容
- Array(數(shù)組)基礎(chǔ)
- 通過 DataSource(數(shù)據(jù)源)顯示tableView內(nèi)容
- 通過 Delegate(委托)使tableView可以響應(yīng)用戶操作
- 使用storyboard的segue實(shí)現(xiàn)基本的頁面跳轉(zhuǎn)及界面間傳值
- 字符串的截取
UITableView
教程實(shí)現(xiàn)的這種類似的滾動(dòng)表格的界面所有智能手機(jī)的用戶應(yīng)該都會(huì)很熟悉,微信的聊天界面,淘寶的寶貝列表都是這種結(jié)構(gòu)。這是App最常用的一種控件之一。
UITableView有兩個(gè)重要接口,dataSource和delegate
- dataSource,數(shù)據(jù)源,顧名思義,它定義了列表的每個(gè)cell顯示什么樣數(shù)據(jù)信息。(靜態(tài))
- delegate,委托,定義了列表如何與用戶交互。(動(dòng)態(tài))
讓UITableView顯示內(nèi)容
tableView中的內(nèi)容不實(shí)憑空顯示出來的,絕大多數(shù)情況下,我們列表的信息是通過數(shù)組(Array)這種數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)的,通過如下代碼定義并初始化一個(gè)數(shù)組,里面存儲(chǔ)了我們要顯示的各種各樣的動(dòng)物。
var animalList = ["?? dog", "?? cat", "?? frog", "?? panda", "?? snake",
"?? monkey", "?? fox", "?? bee", "?? shark", "?? puffer",
"?? dolphin", "?? lizard", "?? gorilla", "?? horse", "?? pig",
"?? cow", "?? squirrel", "?? cheetah", "?? whale", "?? rhinoceros"]
將tabelView拖入stroyboard并設(shè)置為全屏顯示,并在ViewController中實(shí)現(xiàn)datasource接口方法
extension ViewController: UITableViewDataSource {
//定義了每個(gè)cell的顯示方式,每次從數(shù)組中取出
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "animal cell", for: indexPath)
cell.textLabel?.text = animalList[indexPath.row]
return cell
}
//定義了列表每個(gè)section有多少行
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return animalList.count
}
//定義了列表有多少區(qū)(section)
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
讓UITableView響應(yīng)用戶點(diǎn)擊
extension ViewController: UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
animalList.insert(animalList.remove(at: indexPath.row), at: 0)
animalsTableView.moveRow(at: indexPath, to: [0,0])
}
}
這時(shí)每次被點(diǎn)擊的行就會(huì)移到列表的頂部,同時(shí)數(shù)組也做相應(yīng)的更新。
Segue實(shí)現(xiàn)頁面跳轉(zhuǎn)并傳值
首先在storyboard中通過拖拽新建一個(gè)ViewController命名,并新建一個(gè)swift文件與ViewController進(jìn)行連接,類名設(shè)置為DetailViewController。
在新的DetailViewController中拖入兩個(gè)Label,調(diào)整大小并用StackView包裹后居中。

并將label與代碼建立連接:
class DetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var fullTitle: String? //用來接收segue傳過來的字符串
@IBOutlet weak var emojiTextView: UILabel!
@IBOutlet weak var nameTextView: UILabel!
}
然后在兩個(gè)Controller之間拖拽新建Segue,將Segue的Identifier設(shè)置為"show detail"
在ViewController中設(shè)置prepare()方法傳值
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = sender as! IndexPath
if segue.identifier == "show detail"{
let vc = segue.destination as! DetailViewController
print(animalList[(indexPath.row)])
vc.fullTitle = animalList[(indexPath.row)]
//注意
// 此處不可以直接對(duì) label.text 字符屬性進(jìn)行操作,因?yàn)榇藭r(shí) label 為 nil
// vc.emojiTextView.text = animalList[(indexPath.row)] 會(huì)導(dǎo)致 crash
}
}
并在DetailViewController中的viewDidLoad中對(duì)字符串進(jìn)行處理并設(shè)置對(duì)應(yīng)的Label顯示指定內(nèi)容
override func viewDidLoad() {
super.viewDidLoad()
//分割字符串,從首字符到指定字符
emojiTextView.text = fullTitle?.substring(to: (fullTitle?.index((fullTitle?.startIndex)!, offsetBy: 1))!)
//分割字符串從制定字符到尾字符
nameTextView.text = fullTitle?.substring(from: (fullTitle?.index((fullTitle?.startIndex)!, offsetBy: 4))!)
self.navigationItem.title = nameTextView.text
}
這樣這個(gè)簡(jiǎn)單的動(dòng)物列表就完成啦