1、UITableView 的編輯模式 進入編輯模式 代碼體現 // 設置 editing 屬性 tableView?.editing = true // 這個設置的時候是有動畫效果的 tableView.setEditing(true, animated: true) // 我一般喜歡的設置方式 ...
1、UITableView 的編輯模式
進入編輯模式
代碼體現
// 設置 editing 屬性 tableView?.editing = true // 這個設置的時候是有動畫效果的 tableView.setEditing(true, animated: true) // 我一般喜歡的設置方式 (寫在 btn 或者 item 的監聽方法裡面) // 實現編輯模式和非編輯模式的切換 tableView.editing = !tableView.editing tableView.setEditing(!tableView.editing, animated: true) @IBAction func editItemAction(sender: AnyObject) { tableView.editing = !tableView.editing }
效果圖
沒有動畫效果
tableView.editing = !tableView.editing
有動畫效果
tableView.setEditing(!tableView.editing, animated: true)
2、 設置某一行能夠進行編輯
cell 的預設編輯模式是 delete
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable. // 單行能夠可選的設置編輯 1. 設置 tableView 的 editing 屬性 2. 實現這個方法 // tableView 的某一行能夠進行編輯模式 // 這個方法不實現,預設是每一行都進入編輯模式 optional public func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool @IBAction func editItemAction(sender: AnyObject) { tableView.setEditing(!tableView.editing, animated: true) } // 這是一個數據源方法 // 設置 tableView 那一行進入編輯模式 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 雙數 row 行進入編輯模式 if indexPath.row % 2 == 0 { return false } return true }
3、 設置某一行編輯模式的樣式
cell 編輯模式枚舉 public enum UITableViewCellEditingStyle : Int { case None // 正常模式 (這一個主要用於 cell 的移動) case Delete // 刪除模式 case Insert // 插入模式 } cell 編輯模式設置 // Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES. // 允許用戶通過實行這個方法來自定義 cell 的編輯樣式, 如果沒有實現這個方法, 所有的 cell 的預設編輯樣式為 UITableViewCellEditingStyleDelete . 只有 editing 屬性設置為 true 的時候才可以看到效果 optional public func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle 代碼 /*! 設置某一行的編輯樣式 */ func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle { let number = indexPath.row % 3 switch number { case 0: print("0") return UITableViewCellEditingStyle.Delete case 1: print("1") return UITableViewCellEditingStyle.Insert default: print("2") return UITableViewCellEditingStyle.None } }
效果:
上部分只是編輯樣式的展示
4、 編輯模式的事件回調
@available(iOS 2.0, *) // 編輯樣式 add 和 delete 附加視圖點擊的回調 optional public func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 預設實現編輯事件回調方法: func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { // 沒有添加任何的功能代碼 } 實現這個方法後,在非編輯模式下,左滑動 cell 會顯示一個 delete 按鈕。
效果:
先進入了編輯模式,查看了每個 cell 的編輯模式的樣式。(cell 的編輯模式的設置看上面的代碼)
在非編輯模式下,只有 cell 的編輯模式是 delete 的,才可以進行左側滑。
關於 cell 側滑功能的實現可以先查看這段代碼, 後續後詳細說明!
** 事件的回調處理 **
實例代碼
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { switch editingStyle { case .Delete: print("Delete") // 移除模型數據(不移除就會報錯) localData.removeAtIndex(indexPath.row) // 刪除某一行 cell tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) case .Insert: print("Insert") let str = "new" + localData[indexPath.row] // 添加模型數據 (不插入就會報錯) localData.insert(str, atIndex: indexPath.row) // 這一步只會刷新插入的哪一行 tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) case .None: print("None") // None 樣式 是給 cell 的移動準備的,這裡永遠也不會列印(移動的時候並不需要插入和刪除) } } /*! 設置某一行的編輯樣式 */ func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle { print(#function) let number = indexPath.row % 3 switch number { case 0: return UITableViewCellEditingStyle.Delete case 1: return UITableViewCellEditingStyle.Insert default: // None 樣式 是給 cell 的移動準備的 return UITableViewCellEditingStyle.None } }
回調效果:
- 進入到編輯模式後,會預設的調用
func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle
, 刷新每一行的 cell 編輯樣式。 - 點擊左邊的刪除按鈕,cell 會出現側滑,顯示一個 delete ,只有點擊了 delete 之後才可以進行刪除。 刪除一個 cell 後,會再一次調用
func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle
方法,刷新每一個 cell 編輯樣式 。(方法調用的個數變少了) - 點擊添加按鈕,cell 不會出現側滑, 直接調用回調方法。會再一次調用
func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle
方法,刷新每一個 cell 編輯樣式 。(cell 個數增加了) - 當 cell 的編輯樣式是
None
的時候, 點擊是沒有任何效果的。
註意點:
由於進行 delete 和 Insert 操作的回調func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle
方法。
所以, cell 編輯模式需要用一個 數組來記錄。來保證, delete 和 Insert 操作之後,和之前 cell 的編輯樣式是對應的。
// 定義一個 空的數組 var cellEditingStyle: [Int] = [] // 設置預設值 for index in 0 ..< localData.count { cellEditingStyle.append(index) } func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { switch editingStyle { case .Delete: print("Delete") localData.removeAtIndex(indexPath.row) // 編輯模式數據刪除 cellEditingStyle.removeAtIndex(indexPath.row) tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) case .Insert: print("Insert") localData.insert("new" + localData[indexPath.row], atIndex: indexPath.row) // 編輯模式數據添加 (設置為 刪除) cellEditingStyle.insert(0, atIndex: indexPath.row) tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) case .None: print("None") // None 樣式 是給 cell 的移動準備的,這裡永遠也不會列印 } } func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle { print(#function) // 獲取對應的數據進行設置 let number = cellEditingStyle[indexPath.row] % 3 switch number { case 0: return UITableViewCellEditingStyle.Delete case 1: return UITableViewCellEditingStyle.Insert default: return UITableViewCellEditingStyle.None } }
使用這種方式
編輯模式的數據可以和 cell 對應的模型數據綁定。一種 MVC 的思想
5、 編輯模式中的選中操作
編輯模式中的選中操作用到的 API:
// 允許在編輯模式下進行單選 // 預設為 No public var allowsSelectionDuringEditing: Bool // default is NO. Controls whether rows can be selected when in editing mode // 允許在編輯模式進行多選 // 預設為 No public var allowsMultipleSelectionDuringEditing: Bool // default is NO. Controls whether multiple rows can be selected simultaneously in editing mode // 當前選中的索引的獲取 // 獲取當前選中單行的索引 public var indexPathForSelectedRow: NSIndexPath? { get } // returns nil or index path representing section and row of selection. // 獲取當前選中多行的索引 public var indexPathsForSelectedRows: [NSIndexPath]? { get } // returns nil or a set of index paths representing the sections and rows of the selection.
代碼演示:
// 進入編輯模式 tableView.editing = !tableView.editing // 編輯模式下單選 tableView.allowsSelectionDuringEditing = true // 編輯模式下多選 tableView.allowsMultipleSelectionDuringEditing = true
我使用的是 tableView.allowsMultipleSelectionDuringEditing = true
來實現單選和多選操作。
tableView.allowsSelectionDuringEditing = true
效果後面介紹。
這種效果也是我們在項目中最常見的
關鍵代碼
@IBAction func editItemAction(sender: AnyObject) { // 非動畫 // tableView.editing = !tableView.editing // tableView.allowsSelectionDuringEditing = !tableView.editing // 在編輯模式下多選 tableView.allowsMultipleSelectionDuringEditing = !tableView.editing // 動畫 ( 建議使用這個 ) tableView.setEditing(!tableView.editing, animated: true) } /* 註釋掉這個代碼就可實現多選 */ // cell 將要選中的回調代理 // 在這個方法中主要進行的是取消上一次選中 func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? { // 這個方法第一次調用的時候 indexPath 為 nil if let selectedRowIndexPath = tableView.indexPathForSelectedRow { // 去除上一次選中 tableView.deselectRowAtIndexPath(selectedRowIndexPath, animated: true) } return indexPath }
選中效果演示:
單選 多選操作當前選中的索引的獲取
// 獲取當前選中單行的索引 public var indexPathForSelectedRow: NSIndexPath? { get } // 獲取當前選中多行的索引 public var indexPathsForSelectedRows: [NSIndexPath]? { get }
最簡單的獲取選中 cell 的方式就是下麵的兩個介面。使用這兩個介面,我們就不需要另外的再去定義變數記錄選中的 cell 。
tableView.allowsSelectionDuringEditing = true 的特別說明:
這個 tableView.allowsSelectionDuringEditing
設置效果是有點讓人疑惑的。在看到多選的效果後,我一直以為 編輯模式下,單選 的效果 和 多選的效果類似,也應該有個 圈圈 事實證明我是錯的!
單選和多選的效果:
普通模式下的不能選擇,單選和多選:
// 這個屬性,預設是 true 的,設置為 false 後,不能進行 cell 的選中操作。
// 同時也禁止了 代理方法選中的回調
tableView.allowsSelection = false
點擊 cell 沒人任何效果!
tableView.allowsSelection = false
tableView.allowsSelection = true
tableView.allowsSelection = true
// 多選為 true 後,單選肯定也為 true
tableView.allowsMultipleSelection = true
編輯模式下的單選:
tableView.editing = true // 編輯模式下,cell 預設是不能進行選中操作的 tableView.allowsSelectionDuringEditing = false
在編輯模式下,預設 cell 預設是不能響應點擊事件的。並且,control view 還是會根據 cell 編輯模式的進行顯示(我們看到的加號 ,減號,空白)。
tableView.allowsMultipleSelection = false
tableView.editing = true tableView.allowsSelectionDuringEditing = true
單選是沒有 圈圈 效果的,就是單純的 cell 高亮。並且,control view 還是會根據 cell 編輯模式的進行顯示(我們看到的加號 ,減號,空白)。
tableView.allowsSelectionDuringEditing = truetableView.editing = true tableView.allowsMultipleSelectionDuringEditing = true
多選模式下,會修改 control view 的顯示,將 加號,減號,空白替換為 圈圈
6、 編輯模式中 cell 的 Move (移動操作)
預設情況下tableView 中的 cell 是不能進行移動操作, 只有在編輯模式下,tableView 的 cell 可以進行移動操作。
簡單的顯示 cell 移動的附加視圖
這隻是簡單的效果顯示
// Data manipulation - reorder / moving support optional public func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) // 進入編輯模式 tableView.editing = !tableView.editing // cell 的移動和排序操作 ( 方法的簡單實現) func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) { } // 消除不必要的影響 /*! 設置某一行的編輯樣式 */ func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle { // 獲取 cell 對應的編輯模式的緩存數據 let number = cellEditingStyle[indexPath.row] % 3 switch number { // 註釋這裡,主要是為了消除,其他功能的影響。 // case 0: // print("0") // return UITableViewCellEditingStyle.Delete // case 1: // print("1") // return UITableViewCellEditingStyle.Insert default: print("2") // 這一個模式是用來排序移動準備用的 return UITableViewCellEditingStyle.None } }
效果:
7、 編輯模式中指定某一行 cell 可以 Move
// 指定哪一個 cell 能夠移動 func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 單數 row 行進入可移動模式 if indexPath.row % 2 == 0 { return false } return true }
效果:
3、tableView 的移動和排序
// Moving/reordering // Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath: // 允許某一行的排序的附加視圖顯示,只用在數據源 實現了 -tableView:moveRowAtIndexPath:toIndexPath: 方法的時候 這個方法才有效 @available(iOS 2.0, *) optional public func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool 傳說中支持移動和排序的方法 // Data manipulation - reorder / moving support @available(iOS 2.0, *) optional public func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) 代碼體現 // cell 的移動和排序操作 func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) { } // 指定哪一個 cell 能夠移動 func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 單數 row 行進入可移動模式 if indexPath.row % 2 == 0 { return false } return true }
效果圖
4、tableView 索引設置
// Index @available(iOS 2.0, *) // 通過實行這個方法,返回一個 string 的數組就可以設置索引 optional public func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? // return list of section titles to display in section index view (e.g. "ABCD...Z#") @available(iOS 2.0, *) // 索引選中的回調 optional public func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int // tell table which section corresponds to section title/index (e.g. "B",1)) 單獨設置索引 // 索引設置 func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? { return ["A","B","C","D","E", "F", "G"] }
效果圖
當只實行單獨設置索引的方法,點擊索引會預設的滾動到索引對應順序的組。
// 索引設置
func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
return ["A","B","C","D","E", "F", "G"]
}
// 告訴表部分對應部分標題/索引(當點擊索引的時候回調用這個方法)
/*
實現這個方法,點擊索引的只會滾動一次,滾動後執行的是索引的回調
*/
func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
print(title , index)
return 3
}
鏈接:https://www.jianshu.com/p/aaf2c88c58f0