【问题标题】:How to add a checkmark to cells in UITableView (using a custom UITableViewCell subclass and dequeueReusableCell)如何为 UITableView 中的单元格添加复选标记(使用自定义 UITableViewCell 子类和 dequeueReusableCell)
【发布时间】:2020-12-31 15:27:09
【问题描述】:

我想为我的表格视图单元格添加复选标记。我想只在我的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]
        
    }

视图控制器:

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,所以使用自定义单元格的额外皱纹给我带来了一些困惑。非常感谢任何指导!

【问题讨论】:

    标签: ios swift uitableview custom-cell accessorytype


    【解决方案1】:

    抱歉,您的方法完全错误。切勿将 视图 用作数据源类型。不要。

    创建一个模型,这是一个带有nameisSelected 属性的简单示例

    struct Model {
        let name : String
        var isSelected = false
    }
    

    控制器ViewController声明一个包含Model实例的数据源数组

    var arrayOne = [Model(name: "Foo"), Model(name: "Bar"), Model(name: "Baz")]
    

    numberOfRows 的扩展中只返回数组中的项目数(你的guard 表达式根本没有意义),在cellForRow 中设置复选标记取决于isSelecteddidSelect 切换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!
            
    }
    

    这种方法的好处是 modelview 始终保持同步。

    【讨论】:

    • 感谢您的回复!我确实有一个一直在使用的数据模型,但我会考虑将更多/所有数据添加到其中。
    【解决方案2】:

    你应该在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
        }
    

    【讨论】:

    • 谢谢! cell.accessoryType 现在为我工作。它只是不是在 Xcode 中自动填充(这让我很难过)。
    【解决方案3】:

    不确定你想做什么。表格视图的常用方法是不将 tableviewcell 保存在数组中。模型-视图-控制器 (MVC) 方式是将单元格的内容(文本、图像、checkedOrNotChecked)保存在视图控制器内的结构或对象数组中(该数组即模型)。然后在 CellForRow 中,使用 array[indexPath.row] 元素设置单元格的内容,如果选中OrNotCheckindicator,则将 cell.accessoryType 设置为复选标记(单元格是视图)。 在 didSelectRow 中,您只需设置 indexPath.row 元素的 checkOrNotCheck 指示符,然后重新加载表格视图或重新加载 indexPath 处的单元格。 ViewController 是 MVC 中的控制器

    【讨论】:

    • 谢谢!这对理解很有帮助。
    猜你喜欢
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多