单击按钮

时间:2018-10-09 18:39:52

标签: ios swift uitableview

我有一个UITableView,用于显示自定义对象的数组。每个对象都有几个属性,包括一个布尔属性,该布尔属性指示此项是否为新项目。

我的UITableViewCell内容视图在情节提要中定义,并具有类似于以下内容的初始布局:

enter image description here

UITableViewController中,当我使单元出队时,我在UITableViewCell上调用一个方法,该方法将数据配置为在单元中显示,然后再返回。我检查的属性之一是前面提到的.isNew属性。如果该值为true,那么我将创建一个UIButton并将其作为子视图插入到单元格的内容视图中,因此最终得到这样的结果:

enter image description here

仅出于上下文考虑,此按钮将显示“新”图像以指示该项目是新的。我还连接了一种在点击按钮时将触发的方法。该方法也在我的UITableViewCell中定义,如下所示:

@objc func newIndicatorButtonTapped(sender: UIButton!) {
   // call delegate method and pass this cell as the argument
   delegate?.newIndicatorButtonTapped(cell: self)
}

我还创建了一个定义委托方法的协议。我的UITableViewController符合此要求,当我点击单元格中的按钮时,我看到该代码触发。这是委托方法(在我的UITableViewController的扩展名中定义):

func newIndicatorButtonTapped(cell: UITableViewCell) {        
    if let indexPath = self.tableView.indexPath(for: cell) {
        print(indexPath.row)
    }
}

当我点击单元格时,我看到indexPath中的行在Xcode中正确打印。当用户点击此按钮时,我需要将其删除(该按钮)并更新UILabel的约束,以使其再次与内容视图的前沿对齐,如上面的第一个模型所示。不幸的是,我似乎遇到了单元回收的问题,因为UIButton在滚动浏览不同的单元格时消失并重新出现。我是否需要在回收之前重新设置电池的布局/外观,还是对电池回收的工作方式误解了?任何提示将不胜感激!

2 个答案:

答案 0 :(得分:1)

您可能在想的是,您获得了一个“新”单元格,但是当一个单元格被回收时,这意味着它被 重新使用

通过更改基本单元格的文本颜色,您可以很容易地看到这一点。

例如:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "MyID", for: indexPath) as! MyCustomCell

    if indexPath.row == 3 {
        cell.theLabel.textColor = .red
    }

    return cell
}

如您所料,当表第一次加载时,第4行的文本颜色将更改(行索引从零开始)。

但是,假设您有100行?滚动时,单元格将被重用 ...,并且每当原始第4个单元格被重用时,它仍将带有红色文本。

因此,正如您所猜测的,是的……您需要在每次使用它时将其单元格“重置”为其原始布局/内容/颜色/等:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "MyID", for: indexPath) as! MyCustomCell

    if indexPath.row == 3 {
        cell.theLabel.textColor = .red
    } else {
        cell.theLabel.textColor = .black
    }

    return cell
}

答案 1 :(得分:1)

您可能希望考虑隐藏按钮,然后在单击按钮时更改布局。

enter image description here

使用协议将操作从单元格移至tableView,然后在单元格重用时重置布局是一种好方法

在完全编程的单元格中执行以下操作:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! Cell
    cell.isNew = indexPath.row == 0 ? true : false
    cell.layoutIfNeeded()
    return cell
}

单元格类需要类似于:(您可以通过更改“自动布局”约束,直接操作框架或使用UIStackView来执行所需的操作)

class Cell: UITableViewCell {
    var isNew: Bool = false {
        didSet {
            if isNew {
                button.isHidden = true
                leftConstraint.constant = 20
            } else {
                button.isHidden = false
                leftConstraint.constant = 100
            }                    
            self.setNeedsLayout()
        }
    }
    var button: UIButton!
    var label: UILabel!
    var leftConstraint: NSLayoutConstraint!
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        button = UIButton(type: .system)
        button.setTitle("Click", for: .normal)
        self.contentView.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.widthAnchor.constraint(equalToConstant: 50).isActive = true
        button.heightAnchor.constraint(equalToConstant: 10).isActive = true
        button.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20).isActive = true
        button.topAnchor.constraint(equalTo: self.topAnchor, constant: 20).isActive = true

        label = UILabel()
        label.text = "Label"
        self.contentView.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.widthAnchor.constraint(equalToConstant: 200).isActive = true
        label.heightAnchor.constraint(equalToConstant: 20).isActive = true
        label.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
        leftConstraint = label.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 100)
        leftConstraint.isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}