Swift TableView 的多选复选实现

4,057 阅读3分钟

本来是不想贴出来这篇文章的,因为这种东西实现起来实在是没有什么技术难度。之所以写出来是因为之前 OC 造的轮子,Swift 又造了一遍,顺便就写了吧,记录下。 实现 TableView 的复选主要有三种方法: ##一、自定义样式 自定义选中的图片,未选中的图片。如图:

自定义

基本思想:创建一个数组来存储选中的 cell 的 indexpath,然后数组中有的就把 cell 的图片换为选中的图片,没有的就展示未选中的图片

示例代码:

import UIKit

class 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 来实现

mark实现


import UIKit

class 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 UIKit

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

Demo下载