UITableView編輯模式大全解

来源:https://www.cnblogs.com/jukaiit/archive/2019/01/11/10256226.html
-Advertisement-
Play Games

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
        }
    }

 

回調效果:

   
  1. 進入到編輯模式後,會預設的調用 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle, 刷新每一行的 cell 編輯樣式。
  2. 點擊左邊的刪除按鈕,cell 會出現側滑,顯示一個 delete ,只有點擊了 delete 之後才可以進行刪除。 刪除一個 cell 後,會再一次調用 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle方法,刷新每一個 cell 編輯樣式 。(方法調用的個數變少了)
  3. 點擊添加按鈕,cell 不會出現側滑, 直接調用回調方法。會再一次調用 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle 方法,刷新每一個 cell 編輯樣式 。(cell 個數增加了)
  4. 當 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 = true
tableView.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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、收到郵件顯示: 二、存儲過程代碼部分: BEGIN SET NOCOUNT ON; --初始化 Declare @MailTo nvarchar(max) Declare @MailCc nvarchar(max) Declare @MailBcc nvarchar(max) Declare @ ...
  • 1。表結構相同的表,且在同一資料庫(如,table1,table2)Sql :insert into table1 select * from table2 (完全複製)insert into table1 select distinct * from table2(不複製重覆紀錄)insert i ...
  • 多表聯查: select p.*,s.Sheng , i.Shifrom [dbo].[ProductRecordInfo] --表名 p left join [ShengInfo] s on p.ShengInfo = s.ShengId --使用left join左連接 讓兩個表中的指定欄位產生 ...
  • 進程堵塞處理方法: select * from sys.sysprocesses where blocked <>0 and DB_NAME(dbid)='GSHCPDB' ##查詢堵塞進程 dbcc inputbuffer(74) select * from sys.sysprocesses wh ...
  • 今天遇到了一個關於資料庫一致性錯誤的案例。海外工廠的一臺SQL Server 2005(9.00.5069.00 Standard Edition)資料庫在做DBCC CHECKDB的時候出現了一致性錯誤,下麵總結一下處理過程。具體的一致性錯誤信息如下所示: Msg 8992, Level 16, ... ...
  • https://www.cnblogs.com/wchxj/p/8159609.html 問題描述 場景:我們的應用系統是分散式集群的,可橫向擴展的。應用中某個介面操作滿足以下一個或多個條件: 1. 介面運行複雜代價大, 2. 介面返回數據量大, 3. 介面的數據基本不會更改, 4. 介面數據一致性 ...
  • 上一篇我們說了創建一個簡單的顯示報表,但在實際工作中,我們有很多要帶條件的報表 現在先認識一下報表數據,首次打開SSDT,報表數據在視窗的左側,要是找不到了,沒關係,在工具欄-視圖-最下麵的報表數據 下麵我們通過簡單的方式創建一個帶條件的報表 可以通過先創建參數再修改Sql語句,我在這裡為了簡單通過 ...
  • 巨杉資料庫目前已經在超過50家大型商業銀行核心業務上線使用,本文為銀行金融科技轉型應用系列文章第一篇,此後巨杉還將陸續推出銀行業應用和科技創新文章,大家敬請期待。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...