本来是不想贴出来这篇文章的,因为这种东西实现起来实在是没有什么技术难度。之所以写出来是因为之前 OC 造的轮子,Swift 又造了一遍,顺便就写了吧,记录下。 实现 TableView 的复选主要有三种方法: ##一、自定义样式 自定义选中的图片,未选中的图片。如图:
基本思想:创建一个数组来存储选中的 cell 的 indexpath,然后数组中有的就把 cell 的图片换为选中的图片,没有的就展示未选中的图片
示例代码:
import UIKitclass ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! // 创建一个数组用来存储选中的 cell 的行 var selectedIndexs: [Int] = [] override func viewDidLoad() { super.viewDidLoad() }}extension ViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath) as! MultipleChoiceTableViewCell //判断该行原先是否选中 if let index = selectedIndexs.index(of: indexPath.row){ // 先移除之前选中现在不选中的行 selectedIndexs.remove(at: index) //原来选中的取消选中 cell.selectImage.image = UIImage(named:"未点击") }else{ // 先添加选中行的数据 selectedIndexs.append(indexPath.row) // 然后视图改变图片为选中的图片 cell.selectImage.image = UIImage(named:"点击") } //刷新该行,刷新点击行的状态就行了 ,刷新整个 tableView 没有必要,cell 的图片就是选中或者未选中的样子了 self.tableView?.reloadRows(at: [indexPath], with: .automatic) } }extension ViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 30 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "MultipleChoiceTableViewCell", for: indexPath) as! MultipleChoiceTableViewCell //判断是否选中 if selectedIndexs.contains(indexPath.row) { // 如果数组中包含则选中 cell.selectImage.image = UIImage(named:"点击") } else { // 不包含则不选中 cell.selectImage.image = UIImage(named:"未点击") } return cell } } 复制代码
##二、使用 cell 的 mark 来实现 基本思想: 使用 tableView 的 allowsMultipleSelection 来实现
import UIKitclass FirstViewController: UIViewController { @IBOutlet weak var tableView: UITableView! var array = [Int]() override func viewDidLoad() { super.viewDidLoad() for i in 0...30 { array.append(i) } tableView.reloadData() //设置允许单元格多选,也可以在 StoryBoard 中设置,本例使用的是 storyboard 如果不设置就是单选 // tableView.allowsMultipleSelection = true } func getSelectRows() { // 获取 tableView 被 select 的 row,是一个数组 if let selecteRows = tableView!.indexPathsForSelectedRows { for indexPath in selecteRows { print(indexPath.row) } } }}extension FirstViewController: UITableViewDelegate { // 选中 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let cell = self.tableView?.cellForRow(at: indexPath) cell?.accessoryType = .checkmark } // 取消选中 func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { let cell = self.tableView?.cellForRow(at: indexPath) cell?.accessoryType = .none } }extension FirstViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return array.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) // 标记对勾的颜色 cell.tintColor = UIColor.brown //判断是否选中,如果 tableView有 select 的 row ,就把 cell 标记checkmark if let _ = tableView.indexPathsForSelectedRows?.index(of: indexPath){ cell.accessoryType = .checkmark } else { cell.accessoryType = .none } return cell } }复制代码
##三、 使用编辑状态实现多选 基本思想: 编辑状态下,allowsMultipleSelectionDuringEditing设置为 true ,允许在多选。使用长按手势实现点击,为什么不用 tableView 的 delegate 的 select 方法呢? 因为 select 方法里边实现会退出编辑,系统的编辑选中样式会不停地消失出现
实现代码:
import UIKitclass SecondViewController: UIViewController { @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() // 允许编辑 tableView.isEditing = true //编辑状态下允许多选 tableView.allowsMultipleSelectionDuringEditing = true // 长按手势 let longPress = UILongPressGestureRecognizer(target:self, action:#selector(longPressed)) longPress.delegate = self longPress.minimumPressDuration = 1.0 // 添加长按手势 tableView.addGestureRecognizer(longPress) }}extension SecondViewController: UITableViewDelegate { // 选中 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { }}extension SecondViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 30 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) // 选中的颜色 cell.tintColor = UIColor.brown return cell } }extension SecondViewController: UIGestureRecognizerDelegate { // 长按事件响应 func longPressed(gestureRecognizer:UILongPressGestureRecognizer) { if (gestureRecognizer.state == .ended) { if(self.tableView!.isEditing == false) { // 选中 self.tableView!.setEditing(true, animated:true) } else { // 取消选中 self.tableView!.setEditing(false, animated:true) } } }}extension Array { //Array方法扩展 , 将数组进行排序,然后就可以根据 tableViewCell 的 indexPath 来进行删除 等操作了 mutating func removeAt(indexes: [Int]) { for i in indexes.sorted(by: >) { self.remove(at: i) } }}复制代码