本来是不想贴出来这篇文章的,因为这种东西实现起来实在是没有什么技术难度。之所以写出来是因为之前 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 来实现
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)
}
}
}