如何使用一个 UIButton 从 UITableView 中选择和取消选择所有复选标记?
Posted
技术标签:
【中文标题】如何使用一个 UIButton 从 UITableView 中选择和取消选择所有复选标记?【英文标题】:How to select and deselect all the checkmarks from a UITableView with one UIButton? 【发布时间】:2015-12-07 20:47:09 【问题描述】:如何一键选择和取消选择此 UITableView 中的所有单元格?
我在使用此按钮时遇到问题。所以,我的想法是,当我点击它时,UITableView 中的所有单元格都有一个复选标记(选择),当我再次单击它时,所有单元格都没有复选标记(取消选择)。
我已经实现了 UIButton 在单击后更改名称(从“全选”到“取消全选”,反之亦然)。
这些是我写的:
let locationItems:[String] = ["China", "United States", "South Africa", "Spain", "Australia", "Brazil", "Colombia", "Nigeria", "India"]
var selectedItemsIndex:Int?
var selectIndicator = true
@IBOutlet var tableViewWithOptions: UITableView!
@IBOutlet var selectAllLabel: UIButton!
@IBAction func selectAllButton(sender: AnyObject)
if (selectIndicator == true)
if selectAllLabel.titleLabel?.text == "Select all"
selectAllLabel.setTitle("Deselect all", forState: UIControlState.Normal)
selectIndicator = false
else
if selectAllLabel.titleLabel?.text == "Deselect all"
selectAllLabel.setTitle("Select all", forState: UIControlState.Normal)
selectIndicator = true
tableViewWithOptions.reloadData()
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
if let index = selectedItemsIndex
let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: index, inSection: 0))
cell?.accessoryType = .None
let cell = tableView.cellForRowAtIndexPath(indexPath)
cell?.accessoryType = .Checkmark
请告诉我。 谢谢!
【问题讨论】:
您需要首先让您的数据模型跟踪当前选择的行。 您无法在单元格中跟踪选择状态(使用附件类型),您需要一些其他变量。我推荐一个 NSMutableIndexSet。选择一个单元格意味着将行添加到集合中,取消选择意味着将其删除。全选是通过 addIndexesInRange 完成的,取消全选只是为了清除索引集 【参考方案1】:将您的 UITableViewCells 视为只是在数据源中显示您的数据,更容易认为它们只能呈现信息,而要呈现新信息,您必须更新数据源并重新加载表格视图。
我看到您的数据源是locationItems
,它是一个字符串数组。如果将项目的类型更改为 String 和 Bool 类型的元组,则可以将位置名称和 bool 分配给数组中的单个元素,bool 表示选中(true)或未选中(false)
所以把locationItems
改成:
//out data source, contains an array of Tuples containing a string and a bool
let locationItems:[(String, Bool)] = [("China", true), ("United States",false), ("South Africa", false), ("Spain", true), ("Australia", true), ("Brazil", false), ("Colombia", true), ("Nigeria", true), ("India", true)]
正如你在上面看到的,数组中的每个元素都包含一个String和一个Bool,这个bool表示一个国家是否被选中。
所以要“检查”所有单元格,我们将更改数据源中的值并重新加载 tableView。这将导致再次调用cellForRow
,然后单元格将拥有来自我们更新的数据源的新数据。
@IBAction func selectAllButton(sender: AnyObject)
//loop through our data source and change the bool in each element to true
//to indicate that all locations are checked
for item in locationItems
//access second item in the tuple which is our bool and set it's value to true
item.1 = true
tableView.reloadData()
因此,您如何执行此操作的一般要点是您编辑 tableView 从中获取数据的数据源,而不是直接更改单元格。
【讨论】:
【参考方案2】:正如其他人指出的那样,您必须为您的位置及其选择状态维护一个数据模型,以便轻松处理您的场景。您可以为您的位置信息定义一个简单的模型。在 ViewController
类中定义此模型 struct
。
位置模型
struct Location
var name: String
var selected: Bool
init(_ name: String, _ selected:Bool)
self.name = name
self.selected = selected
现在您的模型已定义,您需要加载数据源和属性的初始值。 [注意:你也可以使用帮助类来填充你的数据源。]
var selectionStateIndicator = false
var locationItems: [Location] =
var _locations = [Location]()
var locationNames = ["China", "United States", "South Africa", "Spain", "Australia", "Brazil", "Colombia", "Nigeria", "India"]
for location in locationNames
_locations.append(Location(location, false))
return _locations
()
更新您的cellForRowAtIndexPath
方法以使用新的数据模型来显示数据。
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel?.text = self.locationItems[indexPath.row].name
cell.accessoryType = self.locationItems[indexPath.row].selected ? .Checkmark : .None
return cell
更新您的selectAllButton
操作以使用新模型对象并更新每一行的选择状态。
@IBAction func selectAllButton(sender: AnyObject)
selectionStateIndicator = !selectionStateIndicator
for var location in locationItems
location.selected = selectionStateIndicator
tableViewWithOptions.reloadData()
更新您的didSelectRowAtIndexPath
方法,以便每当有单独的行选择时,您都会相应地更新该行。
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
let cell = tableView.cellForRowAtIndexPath(indexPath)
locationItems[indexPath.row].selected = !locationItems[indexPath.row].selected
if !locationItems[indexPath.row].selected
cell?.accessoryType = .None
else
cell?.accessoryType = .Checkmark
【讨论】:
以上是关于如何使用一个 UIButton 从 UITableView 中选择和取消选择所有复选标记?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 UITableView Cell 中以编程方式创建 n 个 UIButton?