【问题标题】:Dynamically update an ImageView in a tableview section动态更新 tableview 部分中的 ImageView
【发布时间】:2020-06-08 22:03:27
【问题描述】:

我有一个包含 2 个(或更多)部分的表格视图。我已经在其中添加了一个 ImageView,并且需要根据数组中包含的值在开始时以及在选择/取消选择单元格时更改图像视图。我创建的视图如下,

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let viewHeader = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 40))
    buttonCheck = UIButton(type: .custom)
    buttonCheck!.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
    buttonCheck!.tag = section
    buttonCheck!.addTarget(self, action: #selector(tapSection(sender:)), for: .touchUpInside)
    viewHeader.addSubview(buttonCheck!)
}

这很好地添加了 ImageView,当我最初加载表数据时,我需要以编程方式设置图像视图。要更改我所做的图像视图,

if tableViewData.contains(where: self.tags.contains) {
   buttonCheck!.setImage(UIImage(named: "CheckmarkCircle"), for: .normal)
} else {
   buttonCheck!.setImage(UIImage(named: "DeselectedCheckmarkCircle"), for: .normal)
}

我在 didSelectRowAtdidDeselectRowAt 方法中调用了这个。这里的问题是,当我从第一个部分(部分 = 0)中选择一个单元格时,它会影响到第二部分(部分 = 1)标题图像视图。在其他工作中,当我从第一节中选择一个单元格时,第二节的标题图像正在发生变化。我该如何解决这个问题?

【问题讨论】:

    标签: ios swift tableview


    【解决方案1】:

    我认为问题在于您每次调用 viewForHeaderInSection 时都会覆盖 buttonCheck,这意味着它将始终包含对您创建的最后一个按钮的引用。

    如果您创建一个字典来保存图像视图(其中索引是部分)会更好,就像在控制器范围内这样:

    var imageViews: [Int: UIButton] = [:]
    

    然后把viewForHeaderInSection改成这样:

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let viewHeader = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 40))
        let buttonCheck = UIButton(type: .custom)
        buttonCheck!.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
        buttonCheck!.tag = section
        buttonCheck!.addTarget(self, action: #selector(tapSection(sender:)), for: .touchUpInside)
        imageViews[section] = buttonCheck
        viewHeader.addSubview(buttonCheck!)
    }
    

    然后在didSelectdidDeselect 上更新imageView:

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        imageViews[indexPath.section]?.setImage(UIImage(named: "CheckmarkCircle"), for: .normal)
    }
    
    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        imageViews[indexPath.section]?.setImage(UIImage(named: "DeselectedCheckmarkCircle"), for: .normal)
    }
    

    请考虑到性能方面的问题,这可能不是最佳解决方案。最好创建一个扩展 UITableViewHeaderFooterView 的自定义视图并考虑视图的可重用性。

    【讨论】:

    • 只是为了我的好奇心:标题不可重复使用吗?这种方法只有在所有标头都只创建一次并且从不重复使用的情况下才能正常工作。
    • @lennartk 标头也可以重复使用。是的。我相信如果视图被重用,字典会有不同的部分指向同一个视图。
    【解决方案2】:

    您可以采取多种方法。快速而肮脏的方法是只调用tableView.reloadData(),这将强制您的 TableView 中的每个元素重新加载来自 DataSource 的当前数据。

    如果您想采用更高效的方法,您可以选择仅通过循环重新加载节标题。这在this 问题中得到了很好的回答。祝你好运。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 2013-07-19
      • 2012-09-29
      相关资源
      最近更新 更多