2015年9月9日 星期三

第 5 個程式:Table View 中 Cell 的刪除 1


要刪除 Table View Cell 的資料,該如何做? 其執行步驟如下:

1. 開啟 Table View 的 Data Model 為 Edit 編輯模式
2. 在此模式下刪除資料
3. UI 畫面重整 Refresh

Table View Cell 的資料來源依據 MVC (Model-View-Controller) 這架構,其來源是由其協定 UITableViewDataSource 實作。參考 UITableViewDataSource [1] 文件,其提供下列方法:

方法 tableView(_:commitEditingStyle:forRowAtIndexPath:) 會將此 Data Model 切換成 Edit 編輯模式,讓我們可以修改資料,此方法詳細內容如下:
由以上說明得知: 當開啟此 Edit 編輯模式之後,除 insertion (green plus) control 外,亦提供 deletion (red minus) control 用來刪除 Cell 上的資料。 我們使用 func tableView(_ tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 這方法來開啟成 Edit 模式。然後,在此模式下實作我們要刪除的資料。

    override func tableView(tableView: UITableView,
        commitEditingStyle editingStyle: UITableViewCellEditingStyle,
        forRowAtIndexPath indexPath: NSIndexPath) {
            
            if editingStyle == .Delete {
                self.vocabulary.removeAtIndex(indexPath.row)
            }
    }
當資料刪除後,我們必須讓 UI 畫面重整 Refresh。UITableView 提供一個方法 reloadData() 來 refresh UI:

    override func tableView(tableView: UITableView,
        commitEditingStyle editingStyle: UITableViewCellEditingStyle,
        forRowAtIndexPath indexPath: NSIndexPath) {
            
            if editingStyle == .Delete {
                self.vocabulary.removeAtIndex(indexPath.row)
                self.tableView.reloadData()
            }
    }

驗證: 在模擬器上,選取一行資料 Cell,然後左滑:
此時這行的右邊會顯示 Delete 刪除這按鈕。當我們點選這按鈕後,這行會被刪除嗎?
Yeah! 這行真的被刪除了!這下可以鬆口氣! 後記: 這整個步驟是參考書中的練習,以及 Apple 的網站,先由一個該怎麼做的概念去進行,把該有的 code 準備好後,才發現原來 TableViewController 這 Template 很貼心幫我們準備好 code 如下,但貼上自己寫的,整個觀念會更清楚。

  /*
    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
   */
附記: 程式碼:

//
//  MyTableViewController.swift
//  SimpleTableViewControllerDemo
//
//  Created by Elvis Meng on 2015/9/6.
//  Copyright (c) 2015年 Elvis Meng. All rights reserved.
//

import UIKit

class MyTableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
    
    var vocabulary = ["book","pen","queen","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"]

    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return self.vocabulary.count
    }
   
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        
        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! UITableViewCell

        // Configure the cell...
        cell.textLabel?.text = vocabulary[indexPath.row]
        
        return cell
    }

    override func tableView(tableView: UITableView,
        didSelectRowAtIndexPath indexPath: NSIndexPath) {
            
            let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
            if cell.accessoryType == UITableViewCellAccessoryType.None {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
            } else {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
            tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }
    
    override func tableView(tableView: UITableView,
        didDeselectRowAtIndexPath indexPath: NSIndexPath) {
            let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
            if cell.accessoryType == UITableViewCellAccessoryType.None {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
            } else {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
            tableView.deselectRowAtIndexPath(indexPath, animated: false)
    }

    override func tableView(tableView: UITableView,
        commitEditingStyle editingStyle: UITableViewCellEditingStyle,
        forRowAtIndexPath indexPath: NSIndexPath) {
            
            if editingStyle == .Delete {
                self.vocabulary.removeAtIndex(indexPath.row)
                self.tableView.reloadData()
            }
    }

  /*
    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
   */

    /*
    // Override to support rearranging the table view.
    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO if you do not want the item to be re-orderable.
        return true
    }
    */

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */

}

參考: 1. UITableViewDataSource Protocol Reference, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/ 2. UITableView Class Reference, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableView_Class/index.html#//apple_ref/occ/cl/UITableView

沒有留言:

張貼留言

prettyPrint();