Swift:多个 TableView 复选标记 - select 所有行
Swift: Multiple TableView checkmark - select all rows
可以在 TableView 中添加一个 select all
选项 Multiple checkmarks...?
我准备好了代码,我尝试做这个功能。请帮助我!
代码:
struct Area {
let name : String
var isSelected : Bool
init(name : String, isSelected : Bool = false) {
self.name = name
self.isSelected = isSelected
}
}
var areas = [Area(name: "Select all"),Area(name: "a"),Area(name: "b"),Area(name: "c"),Area(name: "d"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return areas.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let area = areas[indexPath.row]
cell.textLabel?.text = area.name
cell.accessoryType = area.isSelected ? .checkmark : .none
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
areas[indexPath.row].isSelected.toggle()
tableView.reloadRows(at: [indexPath], with: .none)
let selectedAreas = areas.filter{[=12=].isSelected}.map{[=12=].name}
print(selectedAreas)
}
谢谢。
首先您需要为 table 视图启用多重选择
tableView.allowsMultipleSelection = true
tableView.allowsMultipleSelectionDuringEditing = true
Select 所有行
for section in 0..<tableView.numberOfSections {
for row in 0..<tableView.numberOfRows(inSection: section) {
let indexPath = IndexPath(row: row, section: section)
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
}
}
要在选中一行时启用复选标记:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
let area = areas[indexPath.row]
area.isSelected = true
cell.accessoryType = .checkmark
}
}
取消选择时也删除复选标记:
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
let area = areas[indexPath.row]
area.isSelected = false
cell.accessoryType = .none
}
}
如果有帮助,请为这个答案投票。谢谢
首先将您的区域更改为class,这样它将成为参考类型
class Area {
let name : String
var isSelected : Bool
init(name : String, isSelected : Bool = false) {
self.name = name
self.isSelected = isSelected
}
}
现在更改您的 didselect 逻辑
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let area = areas[indexPath.row]
area.isSelected.toggle()
if area.name == "Select all"{
areas = areas.map{[=11=].isSelected = true}
}
tableView.reloadRows(at: [indexPath], with: .none)
let selectedAreas = areas.filter{[=11=].isSelected}.map{[=11=].name}
print(selectedAreas)
}
您必须检查用户是否选择了第一行 ("Select all") 并相应地更新其他行:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// toggle the selected area
areas[indexPath.row].isSelected.toggle()
// save the new state for later use
let isSelected = areas[indexPath.row].isSelected
if indexPath.row == 0 {
// "Select all" was selected – update all areas
for i in 1..<areas.count {
areas[i].isSelected = isSelected
}
// update UI
tableView.visibleCells.forEach { [=10=].accessoryType = isSelected ? .checkmark : .none }
} else {
// update UI
tableView.cellForRow(at: indexPath)?.accessoryType = isSelected ? .checkmark : .none
}
tableView.deselectRow(at: indexPath, animated: true)
}
推荐
要在视觉上分离关注点,您还可以为 "Select all" 行使用自己的 table 视图部分。在这种情况下,需要进行更多更改:
var areas = [
// you do not need an area for "Select all" any longer
Area(name: "a"),
Area(name: "b"),
Area(name: "c"),
Area(name: "d")
]
var allSelected: Bool {
// helper var to see if all areas are currently selected
return areas.filter({![=11=].isSelected}).isEmpty
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 1: return "Areas"
default: return nil
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0: return 1 // select all
case 1: return areas.count
default:
// we should never get here
fatalError()
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.selectionStyle = .none
if indexPath.section == 0 {
cell.textLabel?.text = "Select all"
cell.accessoryType = allSelected ? .checkmark : .none
} else {
let area = areas[indexPath.row]
cell.textLabel?.text = area.name
cell.accessoryType = area.isSelected ? .checkmark : .none
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 {
// (de-)select all
let shouldSelect = !allSelected
for i in 0..<areas.count {
areas[i].isSelected = shouldSelect
}
} else {
areas[indexPath.row].isSelected.toggle()
}
tableView.reloadRows(at: tableView.indexPathsForVisibleRows ?? [], with: .automatic)
}
在didSelectRow
中:
if indexPath.row == 0 { // the first item is the select all button
// find out which areas should be selected
let indicesThatShouldBeSelected = (1..<areas.count).filter { !areas[[=10=]].isSelected }
// update model
indicesThatShouldBeSelected.forEach { areas[[=10=]].isSelected = true }
// update view
tableView.reloadRows(at: indicesThatShouldBeSelected.map { IndexPath(section: 0, row: [=10=]) }, with: .none)
}
您也可以只执行 tableView.reloadData()
,这会重新加载整个 table 视图,而不仅仅是需要重新加载的行。
如果 selectAll
行位于索引 0,请检查该行,然后将所有 isSelected
成员设置为 true
并重新加载整个 table
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
areas.indices.forEach{areas[[=10=]].isSelected = true}
tableView.reloadData()
} else {
areas[indexPath.row].isSelected.toggle()
tableView.reloadRows(at: [indexPath], with: .none)
}
let selectedAreas = areas.filter{[=10=].isSelected}.map{[=10=].name}
print(selectedAreas)
}
如果您想排除要选择的第一项,请删除第一个索引
areas.indices.dropFirst().forEach{areas[[=11=]].isSelected = true}
可以在 TableView 中添加一个 select all
选项 Multiple checkmarks...?
我准备好了代码,我尝试做这个功能。请帮助我!
代码:
struct Area {
let name : String
var isSelected : Bool
init(name : String, isSelected : Bool = false) {
self.name = name
self.isSelected = isSelected
}
}
var areas = [Area(name: "Select all"),Area(name: "a"),Area(name: "b"),Area(name: "c"),Area(name: "d"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return areas.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let area = areas[indexPath.row]
cell.textLabel?.text = area.name
cell.accessoryType = area.isSelected ? .checkmark : .none
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
areas[indexPath.row].isSelected.toggle()
tableView.reloadRows(at: [indexPath], with: .none)
let selectedAreas = areas.filter{[=12=].isSelected}.map{[=12=].name}
print(selectedAreas)
}
谢谢。
首先您需要为 table 视图启用多重选择
tableView.allowsMultipleSelection = true
tableView.allowsMultipleSelectionDuringEditing = true
Select 所有行
for section in 0..<tableView.numberOfSections {
for row in 0..<tableView.numberOfRows(inSection: section) {
let indexPath = IndexPath(row: row, section: section)
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
}
}
要在选中一行时启用复选标记:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
let area = areas[indexPath.row]
area.isSelected = true
cell.accessoryType = .checkmark
}
}
取消选择时也删除复选标记:
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
let area = areas[indexPath.row]
area.isSelected = false
cell.accessoryType = .none
}
}
如果有帮助,请为这个答案投票。谢谢
首先将您的区域更改为class,这样它将成为参考类型
class Area {
let name : String
var isSelected : Bool
init(name : String, isSelected : Bool = false) {
self.name = name
self.isSelected = isSelected
}
}
现在更改您的 didselect 逻辑
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let area = areas[indexPath.row]
area.isSelected.toggle()
if area.name == "Select all"{
areas = areas.map{[=11=].isSelected = true}
}
tableView.reloadRows(at: [indexPath], with: .none)
let selectedAreas = areas.filter{[=11=].isSelected}.map{[=11=].name}
print(selectedAreas)
}
您必须检查用户是否选择了第一行 ("Select all") 并相应地更新其他行:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// toggle the selected area
areas[indexPath.row].isSelected.toggle()
// save the new state for later use
let isSelected = areas[indexPath.row].isSelected
if indexPath.row == 0 {
// "Select all" was selected – update all areas
for i in 1..<areas.count {
areas[i].isSelected = isSelected
}
// update UI
tableView.visibleCells.forEach { [=10=].accessoryType = isSelected ? .checkmark : .none }
} else {
// update UI
tableView.cellForRow(at: indexPath)?.accessoryType = isSelected ? .checkmark : .none
}
tableView.deselectRow(at: indexPath, animated: true)
}
推荐
要在视觉上分离关注点,您还可以为 "Select all" 行使用自己的 table 视图部分。在这种情况下,需要进行更多更改:
var areas = [
// you do not need an area for "Select all" any longer
Area(name: "a"),
Area(name: "b"),
Area(name: "c"),
Area(name: "d")
]
var allSelected: Bool {
// helper var to see if all areas are currently selected
return areas.filter({![=11=].isSelected}).isEmpty
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 1: return "Areas"
default: return nil
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0: return 1 // select all
case 1: return areas.count
default:
// we should never get here
fatalError()
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.selectionStyle = .none
if indexPath.section == 0 {
cell.textLabel?.text = "Select all"
cell.accessoryType = allSelected ? .checkmark : .none
} else {
let area = areas[indexPath.row]
cell.textLabel?.text = area.name
cell.accessoryType = area.isSelected ? .checkmark : .none
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 {
// (de-)select all
let shouldSelect = !allSelected
for i in 0..<areas.count {
areas[i].isSelected = shouldSelect
}
} else {
areas[indexPath.row].isSelected.toggle()
}
tableView.reloadRows(at: tableView.indexPathsForVisibleRows ?? [], with: .automatic)
}
在didSelectRow
中:
if indexPath.row == 0 { // the first item is the select all button
// find out which areas should be selected
let indicesThatShouldBeSelected = (1..<areas.count).filter { !areas[[=10=]].isSelected }
// update model
indicesThatShouldBeSelected.forEach { areas[[=10=]].isSelected = true }
// update view
tableView.reloadRows(at: indicesThatShouldBeSelected.map { IndexPath(section: 0, row: [=10=]) }, with: .none)
}
您也可以只执行 tableView.reloadData()
,这会重新加载整个 table 视图,而不仅仅是需要重新加载的行。
如果 selectAll
行位于索引 0,请检查该行,然后将所有 isSelected
成员设置为 true
并重新加载整个 table
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
areas.indices.forEach{areas[[=10=]].isSelected = true}
tableView.reloadData()
} else {
areas[indexPath.row].isSelected.toggle()
tableView.reloadRows(at: [indexPath], with: .none)
}
let selectedAreas = areas.filter{[=10=].isSelected}.map{[=10=].name}
print(selectedAreas)
}
如果您想排除要选择的第一项,请删除第一个索引
areas.indices.dropFirst().forEach{areas[[=11=]].isSelected = true}