類UITableView表示一個列表檢視,此檢視可以顯示列表,並且列表可以分為多個區間(section)。
顯示列表
假設一個案例:
-
顯示計算機語言清單([“java”,”swift”,”js”]和作業系統的清單 [“Windows”,”OS X”,”Linux”]
-
這個清單在一個UITableView上做分割槽顯示,分為兩個區間
那麼程式碼如下:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Page: UIViewController {
var a : Table!
override func viewDidLoad() {
super.viewDidLoad()
a = Table()
a.frame = CGRect(x: 0,y: 50,width: 300,height: 500)
self.view.addSubview(a)
}
}
class Table : UITableView,UITableViewDataSource,UITableViewDelegate{
let sect = ["Lang","OS"]
let lang = ["java","swift","js"]
let os = ["Windows","OS X","Linux"]
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
self.dataSource = self
self.delegate = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func numberOfSections(in: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let rect = CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 44)
let footerView = UILabel(frame:rect)
footerView.text = sect[section]
return footerView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return section == 0 ?lang.count:os.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let arr = indexPath.section == 0 ? lang:os
let a = UITableViewCell(style: .default, reuseIdentifier: nil)
a.textLabel?.text = String(describing:arr[indexPath.row])
return a
}
}
程式碼建立了三個類,其中的AppDelegate和之前的並沒有什麼不同,Page繼承於UIViewController,也和之前的程式碼類似,只是在載入時把Table作為子檢視加入進來。要特別介紹的是Table。
Table繼承於UITableView,並實現UITableViewDataSource,UITableViewDelegate,在配合程式碼:
self.dataSource = self
self.delegate = self
就指明瞭UITableView的資料來源物件為Table,委託物件也是Table。前者指明此物件是UITableView的資料提供者,後者指明此物件是UITableView的外觀和行為的提供者。
具體資料提供的方法就是在此類內實現方法:
func numberOfSections(in: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return section == 0 ?lang.count:os.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let arr = indexPath.section == 0 ? lang:os
let a = UITableViewCell(style: .default, reuseIdentifier: nil)
a.textLabel?.text = String(describing:arr[indexPath.row])
return a
}
第一個方法告訴TableView此列表共有兩個區間要去顯示。第二個方法告訴TableView此列表每個區間的行數,第三個方法告訴TableView指定的區間和行數的內容是什麼。
作為UITableView的外觀和行為的提供者,具體體現是實現了這些方法:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let rect = CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 44)
let footerView = UILabel(frame:rect)
footerView.text = sect[section]
return footerView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44
}
第一個方法為指定的區間建立一個頭檢視,第二個方法指示指定區間的行高。
協議UITableViewDataSource,UITableViewDelegate還有很多可以實現的方法,具體參考iOS的開發者參考資料。
新增刪除修改
類UITableView不但可以顯示內容,還可以配合很多操作。這些內容的操作的基本流程就是修改資料來源,然後通知TableView重新裝入。程式碼入下:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Page: UIViewController {
var a : Table!
override func viewDidLoad() {
super.viewDidLoad()
a = Table()
a.frame = CGRect(x: 0,y: 50,width: 300,height: 500)
self.view.addSubview(a)
}
}
class Table : UITableView,UITableViewDataSource,UITableViewDelegate{
var sect = NSMutableArray.init(array: ["Lang","OS"])
var lang = NSMutableArray.init(array: ["java","swift","js"])
var os = NSMutableArray.init(array:["Windows","OS X","Linux"])
var t = Timer()
var count = 0
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
self.dataSource = self
self.delegate = self
t.invalidate()
t = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.update), userInfo: nil, repeats: true);
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func update() {
if count == 0 {
os[0] = "Win"
}else if count == 1 {
os.add("FreeBSD")
}else if count == 2 {
lang.removeObject(at: 0)
}
count += 1
if count >= 3 {
t.invalidate()
}
self.reloadData()
}
func numberOfSections(in: UITableView) -> Int {
return sect.count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let rect = CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 44)
let footerView = UILabel(frame:rect)
footerView.text = String(describing: sect[section])
return footerView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return section == 0 ?lang.count:os.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let arr = indexPath.section == 0 ? lang as NSArray :os as NSArray
let a = UITableViewCell(style: .default, reuseIdentifier: nil)
a.textLabel?.text = String(describing:arr[indexPath.row])
return a
}
}
此程式碼和上一節的程式碼相比,不同在於:
-
之前的計算機語言陣列和作業系統資料被改成了可變的陣列,因為在這個程式碼中,我們需要修改資料來驗證對UITableView的修改
-
在Table的init函式內,建立一個Timer,它每秒激發一個定時器事件,在不同的激發次數中,分別對資料做修改、新增、刪除
-
呼叫reload方法,從而讓UITableView重新載入資料
預設提供的刪除和列表重排
可以自己新增按鈕並執行對UITableView的列表的刪除和重排。但是也可以使用它自己提供了刪除和重排的UI。刪除流程是這樣的:
-
使用者設定UITableView為編輯模式
-
系統在當前內容的基礎上,加上刪除按鈕(內容左側,紅色的減號圖示),以及重排按鈕(內容右側)
-
使用者可以選擇點選刪除按鈕,系統向左推移內容,顯示一個delete按鈕
-
使用者點選delete按鈕,系統就會呼叫程式設計師實現的委託物件的函式:func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath:
IndexPath)
重排流程是這樣的:
-
使用者設定UITableView為編輯模式
-
系統在當前內容的基礎上,加上刪除按鈕(內容左側,紅色的減號圖示),以及重排按鈕(內容右側)
-
使用者可以選擇按住拖動重排按鈕,系統視覺化這樣拖動過程
-
使用者拖動完成,系統就會呼叫程式設計師實現的委託物件的函式: func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
程式碼如下:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Page: UIViewController {
var a : LangTableRowOper1?
override func viewDidLoad() {
super.viewDidLoad()
a = LangTableRowOper1()
a!.frame = CGRect(x: 0,y: 200,width: 300,height: 200)
self.view.addSubview(a!)
let b = UIButton()
b.setTitle("edit", for: UIControlState())
b.backgroundColor = UIColor.red
b.addTarget(self, action: #selector(ViewController.edit(_:)), for: .touchDown)
let e = UIButton()
e.setTitle("Done", for: UIControlState())
e.backgroundColor = UIColor.blue
e.addTarget(self, action: #selector(Page.done(_:)), for: .touchDown)
let sv = UIStackView()
sv.backgroundColor = UIColor.gray
sv.axis = UILayoutConstraintAxis.horizontal
sv.distribution = .equalCentering;
sv.alignment = .center;
sv.spacing = 10;
sv.frame = CGRect(x: 0,y: 100,width: 300,height: 50)
sv.addArrangedSubview(b)
sv.addArrangedSubview(e)
sv.translatesAutoresizingMaskIntoConstraints = true
self.view.addSubview(sv)
}
func edit( _ b : UIButton!){
a!.setEditing(true, animated: true)
}
func done( _ b : UIButton!){
a!.setEditing(false, animated: true)
}
}
class Table : UITableView,UITableViewDataSource,UITableViewDelegate{
var arr = NSMutableArray.init(array: ["java","swift","js"])
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
self.dataSource = self
self.delegate = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let a = UITableViewCell(style: .default, reuseIdentifier: nil)
a.textLabel?.text = String(describing: arr[indexPath.row])
return a
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
arr.removeObject(at: indexPath.row) // http://stackoverflow.com/questions/21870680/invalid-update-invalid-number-of-rows-in-section-0
self.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade)
}
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
{
return true;
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let s = sourceIndexPath.row
let d = destinationIndexPath.row
let temp = arr[s]
arr.removeObject(at: s)
arr.insert(temp, at: d)
}
}
注意,程式碼中:
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
{
return true;
}
此函式需要實現,從而告訴UITableView那些行是可以拖動重排的。這裡全部返還true,表示所有內容都可以重排。
TableView的裝飾介面
除了顯示section和row之外,TableView可以加入表頭表位,節頭節尾,幫助程式設計師更好的組織內容。
我們現在來展示了一個有兩個section,每個section有行的介面。通過程式碼加入了表頭表尾、節頭節尾。如下:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Table : UITableView,UITableViewDataSource{
let arrs = [["Row 1","Row 2"],["Row 1"]]
let titles = ["Section Title 1","Section Title 2"]
let footers = ["Section Footer 1","Section Footer 2"]
let tableheader = "Table Header"
let tablefooter = "Table Footer"
convenience init(){
self.init(frame: CGRect.zero, style:UITableViewStyle.grouped)
}
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
self.dataSource = self
self.tableHeaderView = UIView()
self.tableHeaderView!.frame = CGRect(x: 0, y: 0,width: 200,height: 20)
let l = UILabel()
l.text = tableheader
l.frame = CGRect(x: 0, y: 0,width: 200,height: 20)
self.tableHeaderView?.addSubview(l)
self.tableFooterView = UIView()
self.tableFooterView!.frame = CGRect(x: 0, y: 0,width: 200,height: 20)
let f = UILabel()
f.text = tablefooter
f.frame = CGRect(x: 0, y: 0,width: 200,height: 20)
self.tableFooterView?.addSubview(f)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrs[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let a = UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: nil)
a.textLabel?.text = String(arrs[indexPath.section][indexPath.row])
return a
}
func numberOfSections(in tableView: UITableView) -> Int{
return arrs.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
return titles[section]
}
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?{
return footers[section]
}
}
class Page: UIViewController {
var a : Table!
override func viewDidLoad() {
super.viewDidLoad()
a = Table()
a.frame = CGRect(x: 0,y: 30,width: 300,height: 400)
self.view.addSubview(a)
}
}
這裡比較特別的是,函式
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
return titles[section]
}
告訴TableView,每個指定section的頭標題。
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?{
return footers[section]
}
告訴TableView,每個指定section的尾標題。
標記
類UITableView支援對每個行做標記和取消標記,標記可以有多種。其中比較常用的是打對號圖示。如下程式碼,演示瞭如何對每個行打對號和取消打對號:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Table : UITableView,UITableViewDataSource,UITableViewDelegate{
let arr = ["java","swift","js"]
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
self.dataSource = self
self.delegate = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let a = UITableViewCell(style: .default, reuseIdentifier: nil)
a.textLabel?.text = String(arr[indexPath.row])
return a
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
print("did select (indexPath.row)")
self.deselectRow(at: indexPath, animated: false)
if self.cellForRow(at: indexPath)?.accessoryType != .checkmark{
self.cellForRow(at: indexPath)?.accessoryType = .checkmark
}else{
self.cellForRow(at: indexPath)?.accessoryType = .none
}
}
}
class Page: UIViewController {
var a : Table!
override func viewDidLoad() {
super.viewDidLoad()
a = Table()
a.frame = CGRect(x: 0,y: 30,width: 300,height: 400)
self.view.addSubview(a)
}
}
執行起來後,可看到三個行,點選任何一個行都會顯示對號標記在行尾,再點選一次就會取消此標記。查詢UITableViewCellAccessoryType的官方文件可以得到更多的標記型別。
重用cell建立
在之前的程式碼中,每次呼叫到函式:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
需要一個UITableViewCell例項時,都是採用臨時建立的方式。如果建立的UITableViewCell例項比較多時,可以通過重用已經建立的UITableViewCell例項來提高效率。做法就是:
-
註冊一個UITableViewCell類,指定其的重用識別符號
-
通過重用識別符號建立例項
UIKit會在內部對此過程優化。例項程式碼如下:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Table: UITableView,UITableViewDataSource{
let arr = ["javascript","delphi"]
let MyIdentifier = "cell"
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
self.dataSource = self
self.register(UITableViewCell.self, forCellReuseIdentifier: MyIdentifier)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let a = tableView.dequeueReusableCell(withIdentifier: MyIdentifier)!
a.textLabel?.text = String(arr[indexPath.row])
return a
}
}
class Page: UIViewController {
var a : Table!
override func viewDidLoad() {
super.viewDidLoad()
a = Table()
a.frame = CGRect(x: 0,y: 30,width: 300,height: 400)
self.view.addSubview(a)
}
}
複合的Cell
之前的程式碼,建立的Cell都是簡單文字;實際上,每個Cell都可以作為一個容器,裝入更多的元素。如下程式碼展示了一個複合的Cell的建立:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Table : UITableView,UITableViewDataSource{
let arr = ["java","swift","js"]
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
self.dataSource = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let a = UITableViewCell(style: .default, reuseIdentifier: nil)
a.textLabel?.text = String(arr[indexPath.row])
let s = UISwitch()
s.frame = CGRect(x: 0,y: 0,width: 20,height: 20)
s.addTarget(self, action: #selector(Table.action(_:)), for: .valueChanged)
s.isOn = true
a.accessoryView = s
return a
}
func action(_ sender : UISwitch!){
print(sender.isOn)
}
}
class Page: UIViewController {
var a : Table!
override func viewDidLoad() {
super.viewDidLoad()
a = Table()
a.frame = CGRect(x: 0,y: 30,width: 300,height: 400)
self.view.addSubview(a)
}
}
本案例在每個Cell中新增了一個UISwitch按鈕,並且可以如同一般的UIView一樣的響應此按鈕的事件。
預設的Cell風格
可以不必自己定製Cell樣式,而是直接使用系統提供的,這樣你可以通過設定不同的UITableViewCellAccessoryType、文字、文字1、圖片、UITableViewCellStyle而讓Cell外觀變得豐富多彩:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Page: UIViewController {
var a : Table!
override func viewDidLoad() {
super.viewDidLoad()
a = Table()
a.frame = CGRect(x: 0,y: 30,width: 300,height: 400)
self.view.addSubview(a)
}
}
class Row {
var text : String = ""
var text2 : String = ""
var image : UIImage
var access : UITableViewCellAccessoryType
var style : UITableViewCellStyle
init( text : String ,text2:String ,image:UIImage,access:UITableViewCellAccessoryType,style : UITableViewCellStyle){
self.text = text
self.text2 = text2
self.image = image
self.access = access
self.style = style
}
}
class Table: UITableView,UITableViewDataSource{
let arr = [
Row(
text:"java",
text2:"old plain",
image:UIImage.imageWithColor(UIColor.red),
access:UITableViewCellAccessoryType.checkmark,
style: UITableViewCellStyle.value1),
Row(
text:"ruby",
text2:"new cool slow",
image:UIImage.imageWithColor(UIColor.green),
access:UITableViewCellAccessoryType.detailButton,
style: UITableViewCellStyle.value2),
Row(
text:"swift",
text2:"new cool quick ",
image:UIImage.imageWithColor(UIColor.blue),
access:UITableViewCellAccessoryType.detailDisclosureButton,
style: UITableViewCellStyle.subtitle)
]
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
self.dataSource = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let a = UITableViewCell(style: arr[indexPath.row].style, reuseIdentifier: nil)
a.textLabel?.text = arr[indexPath.row].text
a.detailTextLabel?.text = arr[indexPath.row].text2
a.imageView?.image = arr[indexPath.row].image
a.accessoryType = arr[indexPath.row].access
return a
}
}
extension UIImage {
class func imageWithColor(_ color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 10.0,height: 10.0 )
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(color.cgColor)
context?.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
案例顯示了三行,每行有不同的風格組合,都是通過設定UITableViewCellAccessoryType、文字、文字1、圖片、UITableViewCellStyle來達成的。你可以實際執行此程式碼,瞭解不同樣式的差異。可以通過官方手冊查詢UITableViewCellStyle和UITableViewCellAccessoryType的不同選擇。這裡列出的類為UIImage擴充套件出來的方法:
class func imageWithColor(_ color: UIColor) -> UIImage
是為了不必尋找圖片,而可以即席按需建立出可以用於例項的圖片,傳遞不同的顏色值,可以得到不同顏色的小方塊圖片。我們只是需要展示Cell的顯示圖片的能力,因此只有通過程式碼建立出圖就好,不必為此單獨尋找適合工程使用的圖片。
UITableViewController
我們一直使用UITableView,把它加入到一個ViewController內,然後由AppDelegate載入後者。實際上,可以使用UITableViewController直接由AppDelegate載入:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = LangTableViewController()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class LangTableViewController : UITableViewController{
let arr = ["swift","obj-c","ruby"]
let MyIdentifier = "cell"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: MyIdentifier)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let a = tableView.dequeueReusableCell(withIdentifier: MyIdentifier)
a!.textLabel?.text = arr[indexPath.row]
return a!
}
}
和UITableView的使用的不同之處,在於:
-
本來需要實現UITableViewDataSource和UITableViewDelegate的方法,現在已經有UITableViewController實現,作為UITableViewController的子類,新類需要的是覆蓋父類的方法。
-
使用UITableViewController會自動把UITableView填滿AppDelegate.window檢視內。無需程式設計師指定位置和大小。