如何向 UITableView 中的单元格添加复选标记(使用自定义 UITableViewCell 子类和 dequeueReusableCell)
How to add a checkmark to cells in UITableView (using a custom UITableViewCell subclass and dequeueReusableCell)
我想在我的 Table 视图单元格中添加复选标记。我想只在我的 didSelectRowAt
方法中实现 cell.accessoryType = UITableViewCellAccessoryCheckmark
,但是在使用自定义 UITableViewCell
子类时我无法让它工作。
自定义单元格:
class TableCell: UITableViewCell {
@IBOutlet weak var tableLabel: UILabel!
var arrayOneToDisplay:ArrayOne?
let arrayOne = ArrayOne()
func displayTable(_ currentArrayOne:ArrayOne) {
// Keep a reference to the cell
arrayOneToDisplay = currentArrayOne
// Get the Table Cells data
var tableCell = arrayOne.tableCells
// Set the instructionLabel
tableLabel.text = currentArrayOne.tableCells![0]
}
ViewController:
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Make sure the array contains at least 1 item
guard arrayOne.count > 0 else {
return 0
}
// Return the number of items for this array
let currentArrayOne = arrayOne[currentArrayOneIndex!]
if currentArrayOne.tableCells != nil {
return currentArrayOne.tableCells!.count
}
else {
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Get a cell
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell
// Get the instruction that the tableView is asking about
let tableLabel = cell.tableLabel
if tableLabel != nil {
let currentArrayOne = arrayOne[currentArrayOneIndex!]
if currentArrayOne.tableCells != nil && indexPath.row < currentArrayOne.tableCells!.count {
// Set the text for the label
tableLabel!.text = currentArrayOne.tableCells![indexPath.row]
}
}
// Return the cell
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
当我尝试在 ViewController 中实现 cell.accessoryType
时,Xcode 无法识别 accessoryType
。我相信这是因为我的方法是针对 UITableView
而不是 UITableViewCell
,所以使用自定义单元格的额外问题让我有些困惑。非常感谢任何指导!
不确定您要做什么。 table视图通常的做法是不在数组中保存tableviewcell。模型-视图-控制器(MVC)方式是将单元格的内容(文本、图像、checkedOrNotChecked)保存在viewcontroller(数组就是模型)内部的结构或对象数组中。然后在 CellForRow 中,使用 array[indexPath.row] 元素设置单元格的内容,如果 checkedOrNotCheckindicator 设置 cell.accessoryType 为复选标记(单元格是视图)。
在 didSelectRow 中,您只需设置 indexPath.row 元素的 checkOrNotCheck 指示符,然后重新加载 table 视图或重新加载位于 indexPath 的单元格。
Thé ViewController 是 MVC
中的控制器
您应该在 cellForRowAt
方法中设置您的 accessoryType
,尝试将其重写为:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell
cell.accessoryType = .checkmark
guard let arrayOneIndex = currentArrayOneIndex, arrayOneIndex < arrayOne.count else { return cell }
let currentArrayOne = arrayOne[arrayOneIndex]
guard let tableCells = currentArrayOne.tableCells, indexPath.row < tableCells.count else { return cell }
cell.tableLabel.text = tableCells[indexPath.row]
return cell
}
抱歉,您的做法完全错误。永远不要使用 view 作为数据源类型。不要。
创建一个 模型,这是一个具有 name
和 isSelected
属性的简单示例
struct Model {
let name : String
var isSelected = false
}
并在 controller ViewController
中声明一个包含 Model
个实例的数据源数组
var arrayOne = [Model(name: "Foo"), Model(name: "Bar"), Model(name: "Baz")]
在 numberOfRows
的扩展中只是 return 数组中的项目数(你的 guard
表达式根本没有意义),在 cellForRow
中设置复选标记取决于 isSelected
和 didSelect
切换 isSelected
属性 并重新加载行。
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOne.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Get a cell
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell
// Get the item of the data source array
let item = arrayOne[indexPath.row]
// update the view
cell.tableLabel = item.name
cell.accessoryType = item.isSelected ? .checkmark : .none
// Return the cell
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// toggle isSelected of the row in the model
arrayOne[indexPath.row].isSelected.toggle()
// reload the row to update the view
tableView.reloadRows(at: [indexPath], with: .none)
}
}
在自定义单元格中只声明出口,没有其他东西
class TableCell: UITableViewCell {
@IBOutlet weak var tableLabel: UILabel!
}
这种方法的好处是 model 和 view 总是同步的。
我想在我的 Table 视图单元格中添加复选标记。我想只在我的 didSelectRowAt
方法中实现 cell.accessoryType = UITableViewCellAccessoryCheckmark
,但是在使用自定义 UITableViewCell
子类时我无法让它工作。
自定义单元格:
class TableCell: UITableViewCell {
@IBOutlet weak var tableLabel: UILabel!
var arrayOneToDisplay:ArrayOne?
let arrayOne = ArrayOne()
func displayTable(_ currentArrayOne:ArrayOne) {
// Keep a reference to the cell
arrayOneToDisplay = currentArrayOne
// Get the Table Cells data
var tableCell = arrayOne.tableCells
// Set the instructionLabel
tableLabel.text = currentArrayOne.tableCells![0]
}
ViewController:
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Make sure the array contains at least 1 item
guard arrayOne.count > 0 else {
return 0
}
// Return the number of items for this array
let currentArrayOne = arrayOne[currentArrayOneIndex!]
if currentArrayOne.tableCells != nil {
return currentArrayOne.tableCells!.count
}
else {
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Get a cell
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell
// Get the instruction that the tableView is asking about
let tableLabel = cell.tableLabel
if tableLabel != nil {
let currentArrayOne = arrayOne[currentArrayOneIndex!]
if currentArrayOne.tableCells != nil && indexPath.row < currentArrayOne.tableCells!.count {
// Set the text for the label
tableLabel!.text = currentArrayOne.tableCells![indexPath.row]
}
}
// Return the cell
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
当我尝试在 ViewController 中实现 cell.accessoryType
时,Xcode 无法识别 accessoryType
。我相信这是因为我的方法是针对 UITableView
而不是 UITableViewCell
,所以使用自定义单元格的额外问题让我有些困惑。非常感谢任何指导!
不确定您要做什么。 table视图通常的做法是不在数组中保存tableviewcell。模型-视图-控制器(MVC)方式是将单元格的内容(文本、图像、checkedOrNotChecked)保存在viewcontroller(数组就是模型)内部的结构或对象数组中。然后在 CellForRow 中,使用 array[indexPath.row] 元素设置单元格的内容,如果 checkedOrNotCheckindicator 设置 cell.accessoryType 为复选标记(单元格是视图)。 在 didSelectRow 中,您只需设置 indexPath.row 元素的 checkOrNotCheck 指示符,然后重新加载 table 视图或重新加载位于 indexPath 的单元格。 Thé ViewController 是 MVC
中的控制器您应该在 cellForRowAt
方法中设置您的 accessoryType
,尝试将其重写为:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell
cell.accessoryType = .checkmark
guard let arrayOneIndex = currentArrayOneIndex, arrayOneIndex < arrayOne.count else { return cell }
let currentArrayOne = arrayOne[arrayOneIndex]
guard let tableCells = currentArrayOne.tableCells, indexPath.row < tableCells.count else { return cell }
cell.tableLabel.text = tableCells[indexPath.row]
return cell
}
抱歉,您的做法完全错误。永远不要使用 view 作为数据源类型。不要。
创建一个 模型,这是一个具有 name
和 isSelected
属性的简单示例
struct Model {
let name : String
var isSelected = false
}
并在 controller ViewController
中声明一个包含 Model
个实例的数据源数组
var arrayOne = [Model(name: "Foo"), Model(name: "Bar"), Model(name: "Baz")]
在 numberOfRows
的扩展中只是 return 数组中的项目数(你的 guard
表达式根本没有意义),在 cellForRow
中设置复选标记取决于 isSelected
和 didSelect
切换 isSelected
属性 并重新加载行。
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOne.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Get a cell
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell
// Get the item of the data source array
let item = arrayOne[indexPath.row]
// update the view
cell.tableLabel = item.name
cell.accessoryType = item.isSelected ? .checkmark : .none
// Return the cell
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// toggle isSelected of the row in the model
arrayOne[indexPath.row].isSelected.toggle()
// reload the row to update the view
tableView.reloadRows(at: [indexPath], with: .none)
}
}
在自定义单元格中只声明出口,没有其他东西
class TableCell: UITableViewCell {
@IBOutlet weak var tableLabel: UILabel!
}
这种方法的好处是 model 和 view 总是同步的。