tableView.cellForRowAtIndexPath returns nil with too many cells (swift)

前端 未结 1 1507
梦毁少年i
梦毁少年i 2021-01-13 21:40

So I have the weirdest thing;

I am looping a tableView in order to iterate over all cells. It works fine with less than 5 cells, but crashes with \"unexpectedly foun

相关标签:
1条回答
  • 2021-01-13 22:18

    Because cells are reused, cellForRowAtIndexPath will give you cell only if cell for given indexPath is currently visible. It is indicated by the optional value. If you want to prevent from crash, you should use if let

    if let cell = tableView?.cellForRowAtIndexPath(indexPath) as? MenuItemTableViewCell {
         // Do something with cell
    }
    

    If you want to update values from cell, your cells should update the dataSource items. For example you can create delegate for that

    protocol UITableViewCellUpdateDelegate {
        func cellDidChangeValue(cell: UITableViewCell)
    }
    

    Add delegate to your cell and suppose we have a textField in this cell. We add target for the didCHangeTextFieldValue: for EditingDidChange event so it is called every time the user types somethink in it. And when he do, we call the delegate function.

    class MyCell: UITableViewCell {
        @IBOutlet var textField: UITextField!
    
        var delegate: UITableViewCellUpdateDelegate?
    
        override func awakeFromNib() {
            textField.addTarget(self, action: Selector("didCHangeTextFieldValue:"), forControlEvents: UIControlEvents.EditingChanged)
        }
    
        @IBAction func didCHangeTextFieldValue(sender: AnyObject?) {
            self.delegate?.cellDidChangeValue(cell)
        }
    }
    

    Then in cellForRowAtIndexPath you add the delegate

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
        let cell = tableView.dequeueReusableCellWithIdentifier("MyCellIdentifier", forIndexPath: indexPath)
        cell.delegate = self
    
        return cell
    }
    

    And finally we implement the delegate method:

    func cellDidChangeValue(cell: UITableViewCell) {
    
        guard let indexPath = self.tableView.indexPathForCell(cell) else {
            return
        }
    
        /// Update data source - we have cell and its indexPath
    
    }
    

    Hope it helps

    0 讨论(0)
提交回复
热议问题