table view應該是iOS應用中最常用的UI element饶氏。最好的例子就是iPhone自帶的一些應用,如電話有勾,郵件疹启,設置等。TED蔼卡,Google+喊崖,Airbnb,微信等等都是很好例子雇逞。
創(chuàng)建一個項目
- 項目名稱為SimpleTable荤懂,模板為"Single View application"
設計UI
- 選中
Main.storyboard
,從Object library中拖動Table View
進入視圖 - 改變
Table View
的大小至整個view喝峦,修改屬性Prototype Cells
為1 - 選中
Table View Cell
势誊,修改Style
為Basic,Identifier
為Cell谣蠢。table view cell的標準類型有 basic粟耻、right detail查近、left detail 和 subtitle,當然還有定制類型custom挤忙。 - 選中
Table View
霜威,設置四個spacing約束,上下左右的距離都設置為0
為UITableView添加兩個協(xié)議
-
Object library中的每一UI component都是對應一個class册烈,如
Table View
就是對應UITableView
戈泼。可以通過點擊并懸停在UI component上查看對應的class和介紹赏僧。 - 在
ViewController.swift
文件的UIViewController
后大猛,添加代碼, UITableViewDataSource, UITableViewDelegate
,表示ViewController
類實現(xiàn)了UITableViewDataSource
淀零,UITableViewDelegate
兩個協(xié)議挽绩。
出現(xiàn)紅色感嘆號,這是xcode的問題提示驾中,點擊參看問題描述:
Type 'ViewController' does not conform to protocol
'UITableViewDataSource'
問題描述為ViewController
不符合協(xié)議UITableViewDataSource
唉堪。通過command+點擊 (最新的xcode9變成了command+option+點擊)到UITableViewDataSource
中看看你:
public protocol UITableViewDataSource : NSObjectProtocol {
@available(iOS 2.0, *)
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
@available(iOS 2.0, *)
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
@available(iOS 2.0, *)
optional public func numberOfSections(in tableView: UITableView) -> Int // Default is 1 if not implemented
@available(iOS 2.0, *)
optional public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? // fixed font style. use custom view (UILabel) if you want something different
@available(iOS 2.0, *)
optional public func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?
// Editing
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
@available(iOS 2.0, *)
optional public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
...
-
UITableViewDataSource
協(xié)議中定義了很多方法,除了前兩個方法沒有optional
其它都有肩民,有的表示這個方法不一定要實現(xiàn)唠亚,沒有的就一定要實現(xiàn),把這個兩個方法實現(xiàn)了持痰,問題提示就會消失灶搜。這兩個方法從名字和返回值類型也大概能知道做了什么:-
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
一個section有幾行,也就是一個section有幾個UITableViewCell
共啃, section就是一組UITableViewCell
的意思占调,Table View可以定義多個section,默認是一個移剪。 -
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
返回每一行的UITableViewCell
-
在
ViewController.swift
中定義一個變量restaurantNames
究珊,類型是數(shù)組,表示一系列餐館的名字纵苛。
var restaurantNames = ["Cafe Deadend", "Homei", "Teakha", "Cafe Loisl", "PetiteOyster", "For Kee Restaurant", "Po's Atelier", "Bourke Street Bakery", "Haigh'sChocolate", "Palomino Espresso", "Upstate", "Traif", "Graham Avenue Meats AndDeli", "Waffle & Wolf", "Five Leaves", "Cafe Lore", "Confessional","Barrafina", "Donostia", "Royal Oak", "CASK Pub and Kitchen"]
- 定義
UITableViewDataSource
的兩個方法:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// 1
return restaurantNames.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
// 2
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier,
for: indexPath)
// 3
cell.textLabel?.text = restaurantNames[indexPath.row]
return cell
}
- 1 餐館的數(shù)目就是section的行數(shù)
- 2 "Cell"與之前定義的
UITableViewCell
的Identifier
屬性是對應的剿涮。dequeueReusableCell
方法是產(chǎn)生一個UITableViewCell
。 - 3
UITableViewCell
中有可算屬性textLabel
攻人,其實就是一個UILabel
取试,由于是可選屬性,調(diào)用時也用可選鏈式調(diào)用cell.textLabel?.text
連接 DataSource 和 Delegate
運行app怀吻,沒有數(shù)據(jù)顯示瞬浓。盡管上面已經(jīng)在代碼中讓ViewController
繼承了UITableViewDataSource
, UITableViewDelegate
,但storyboard并不知道蓬坡。
- 在document outline中選擇Table View猿棉,使用control-drag到View Controller磅叛,在彈出框中選擇dataSource。同樣的方法選擇delegate
- 確認連接是否成功萨赁。選中Table View弊琴,在connetion檢查器中查看;或者直接在document outline中右擊Table View
-
運行app
添加圖片到Table View
- 從simpletable-image1.zip下載圖片杖爽,解壓后一起拖到asset catalog
- 在
ViewController.swift
的tableView(_:cellForRowAtIndexPath:)
方法的return cell
前添加代碼cell.imageView?.image = UIImage(named: "restaurant")
敲董。使每個UITableViewCell
的image都是一樣的。
隱藏狀態(tài)欄
頂部狀態(tài)來和table view 數(shù)據(jù)重疊了慰安,只要在ViewController
加一段代碼就可以:
override var prefersStatusBarHidden: Bool {
return true
}
prefersStatusBarHidden
是父類UIViewController
中的屬性腋寨,所以要加 override
,表示重寫了化焕。
不同的Cell對應不同的圖片
- 從simpletable-image2.zip下載圖片精置,解壓后一起拖到asset catalog
- 修改
ViewController.swift
的tableView(_:cellForRowAtIndexPath:)
為:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier,
for: indexPath)
// Configure the cell...
let restaurantName = restaurantNames[indexPath.row]
cell.textLabel?.text = restaurantName
// 1
let imageName = restaurantName.lowercased().replacingOccurrences(of: " ", with: "")
if let image = UIImage(named: imageName) {
cell.imageView?.image = image
} else {
cell.imageView?.image = UIImage(named: "restaurant")
}
return cell
}
- 1 把菜館名字字符串先修改成小寫,然后去空格
- 最終結(jié)果
代碼
Beginning-iOS-Programming-with-Swift
說明
此文是學習appcode網(wǎng)站出的一本書 《Beginning iOS 10 Programming with Swift》 的一篇記錄