UITableView 的編輯模式
在稍前表格 UITableView 章節已經介紹過基本的使用方式,其實 UITableView 提供的功能非常的多,這小節會再介紹另一個也是十分常使用到的編輯模式。
以下是本小節目標:
首先在 Xcode 裡,新建一個 Single View Application 類型的專案,取名為 ExEditUITableView 。
並為ViewController
建立兩個屬性以供後續使用:
class ViewController: UIViewController {
var myTableView :UITableView!
var info =
["林書豪","陳信安","陳偉殷","王建民","陳金鋒","林智勝"]
// 省略
}
為了方便設置切換 UITableView 編輯模式的按鈕,這邊先在 AppDelegate.swift 設置 導覽控制器 UINavigationController,後續便可在導覽列左右設置按鈕。
首先在 viewDidLoad() 中設置基本設定、 UITableView 及導覽列按鈕:
// 基本設定
let fullsize = UIScreen.mainScreen().bounds.size
self.view.backgroundColor = UIColor.whiteColor()
self.title = "編輯模式"
self.navigationController?.navigationBar.translucent =
false
// 建立 UITableView
myTableView = UITableView(frame: CGRect(
x: 0, y: 0,
width: fullsize.width,
height: fullsize.height - 64),
style: .Plain)
myTableView.registerClass(
UITableViewCell.self, forCellReuseIdentifier: "Cell")
myTableView.delegate = self
myTableView.dataSource = self
myTableView.allowsSelection = true
self.view.addSubview(myTableView)
// 導覽列左邊及右邊按鈕 編輯 & 新增
myTableView.setEditing(true, animated: false)
self.editBtnAction()
上述將導覽列按鈕另外設置在一個方法editBtnAction()
中,以供切換編輯模式時可以一併變動。
切換編輯模式
按下編輯按鈕來切換編輯模式,如下:
// 按下編輯按鈕時執行動作的方法
func editBtnAction() {
myTableView.setEditing(
!myTableView.editing, animated: true)
if (!myTableView.editing) {
// 顯示編輯按鈕
self.navigationItem.leftBarButtonItem =
UIBarButtonItem(barButtonSystemItem: .Edit,
target: self,
action:
#selector(ViewController.editBtnAction))
// 顯示新增按鈕
self.navigationItem.rightBarButtonItem =
UIBarButtonItem(barButtonSystemItem: .Add,
target: self,
action:
#selector(ViewController.addBtnAction))
} else {
// 顯示編輯完成按鈕
self.navigationItem.leftBarButtonItem =
UIBarButtonItem(barButtonSystemItem: .Done,
target: self,
action:
#selector(ViewController.editBtnAction))
// 隱藏新增按鈕
self.navigationItem.rightBarButtonItem = nil
}
}
上述程式根據 UITableView 的屬性editing
來判斷目前是否處於編輯模式,並使用方法setEditing(_:animated:)
來切換。切換的同時也一併設置新的左右兩邊的按鈕,只有非編輯模式時才有新增的按鈕。
要設置每筆 row 是否可以進入編輯模式,必須實作以下這個委任方法:
// 各 cell 是否可以進入編輯狀態 及 左滑刪除
func tableView(tableView: UITableView,
canEditRowAtIndexPath indexPath: NSIndexPath)
-> Bool {
return true
}
你可以根據 indexPath 來讓特定的 section 的 row 不能編輯。
新增一筆資料
在非編輯模式時,可以按導覽列右邊按鈕新增一筆資料,如下:
// 按下新增按鈕時執行動作的方法
func addBtnAction() {
print("新增一筆資料")
info.insert("new row", atIndex: 0)
// 新增 cell 在第一筆 row
myTableView.beginUpdates()
myTableView.insertRowsAtIndexPaths(
[NSIndexPath(forRow: 0, inSection: 0)],
withRowAnimation: .Fade)
myTableView.endUpdates()
}
上述程式先為示範的陣列新增一筆資料,再在 UITableView 的兩個方法beginUpdates()
與endUpdates()
中間使用方法insertRowsAtIndexPaths(_:withRowAnimation:)
新增一筆資料。
排序切換位置
必須實作下面這個委任方法,才會出現排序功能:
// 編輯狀態時 拖曳切換 cell 位置後執行動作的方法
// (必須實作這個方法才會出現排序功能)
func tableView(tableView: UITableView,
moveRowAtIndexPath sourceIndexPath: NSIndexPath,
toIndexPath destinationIndexPath: NSIndexPath) {
print("\(sourceIndexPath.row) to")
print("\(destinationIndexPath.row)")
var tempArr:[String] = []
if(sourceIndexPath.row > destinationIndexPath.row)
{ // 排在後的往前移動
for (index, value) in info.enumerate() {
if index < destinationIndexPath.row
|| index > sourceIndexPath.row {
tempArr.append(value)
} else if
index == destinationIndexPath.row {
tempArr.append(info[sourceIndexPath.row])
} else if index <= sourceIndexPath.row {
tempArr.append(info[index - 1])
}
}
} else if (sourceIndexPath.row <
destinationIndexPath.row) {
// 排在前的往後移動
for (index, value) in info.enumerate() {
if index < sourceIndexPath.row
|| index > destinationIndexPath.row {
tempArr.append(value)
} else if
index < destinationIndexPath.row {
tempArr.append(info[index + 1])
} else if
index == destinationIndexPath.row {
tempArr.append(info[sourceIndexPath.row])
}
}
} else {
tempArr = info
}
info = tempArr
print(info)
}
上述程式除了重新排序 UITableView 之外,也必須將示範的陣列重新排序。
刪除資料
編輯模式下刪除或是左滑刪除時,會執行以下方法:
// 編輯狀態時 按下刪除 cell 後執行動作的方法
// (另外必須實作這個方法才會出現左滑刪除功能)
func tableView(tableView: UITableView,
commitEditingStyle editingStyle:
UITableViewCellEditingStyle, forRowAtIndexPath
indexPath: NSIndexPath) {
let name = info[indexPath.row]
if editingStyle == .Delete {
info.removeAtIndex(indexPath.row)
tableView.beginUpdates()
tableView.deleteRowsAtIndexPaths(
[indexPath], withRowAnimation: .Fade)
tableView.endUpdates()
print("刪除的是 \(name)")
}
}
除了刪除 UITableView 的資料外,也必須刪除示範陣列所屬的值。
以上即為本小節的示範內容。
範例
本小節範例程式碼放在 apps/todo