在 UITableView 中仅重新加载一个节标题
Posted
技术标签:
【中文标题】在 UITableView 中仅重新加载一个节标题【英文标题】:Reload only one section header in UITableView 【发布时间】:2017-07-03 14:12:05 【问题描述】:我在UITableView
中使用自定义单元格作为部分标题。在那个单元格中有三个按钮。如果在该部分的单元格中单击任何按钮,它应该只重新加载该自定义部分单元格,而不是任何行。这可能吗?
我正在使用以下代码重新加载该单元格:
tableViewHome.reloadSections([1], with: UITableViewRowAnimation.none)
它隐藏了我的部分单元格并扭曲了我的整个表格。
更新
我正在使用UITableView
以及我正在使用的以下代码:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
let cellHeader = tableViewHome.dequeueReusableCell(withIdentifier: "header") as! HeaderTableViewCell
cellHeader.filter1btn.addTarget(self, action: #selector(filterBtnAction(_:)), for: .touchUpInside)
cellHeader.filter2Btn.addTarget(self, action: #selector(filterBtnAction(_:)), for: .touchUpInside)
cellHeader.filter3btn.addTarget(self, action: #selector(filterBtnAction(_:)), for: .touchUpInside)
return cellHeader
@IBAction func filterBtnAction(_ sender: UIButton)
print(sender.tag)
tableViewHome.reloadSections([1], with: UITableViewRowAnimation.none)
【问题讨论】:
【参考方案1】:我有点不清楚这里发生了什么,但听起来这里有一个UITableView
概念值得解释:
UITableView
有自己的单元格概念,实现为UITableViewCell
,以及自己的页眉/页脚概念,实现为UITableViewHeaderFooterView
。
根据您的意思是这两个中的哪一个,您可以做一些事情来获得预期的效果:
UITableViewCell
方法:
如果您使用 UITableViewCell
作为部分的第一行以充当“标题”,并且您只想重新加载该行以排除该部分的其余部分,您可以调用 @987654334 @(Apple Documentation) 这个方法接受一个IndexPath
s 的数组和一个动画样式。您可以传入要重新加载的那个的 indexPath。
UITableViewHeaderFooterView
方法:
如果您使用的是正确的UITableViewHeaderFooterView
,那么您需要确保在重新加载该部分时提供了正确的视图。 Zack Shapiro 概述了您在this answer 中需要采取的步骤:
-
创建一个作为
UITableViewHeaderFooterView
子类的类。
用您的UITableView
实例注册它。
然后在viewForHeaderInSection
,你做let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderView") as! YourHeaderViewSubclass
他最后指出的是:
具有欺骗性的是,当它确实需要
dequeuedReusableHeaderFooterView
或reloadData
时,函数调用返回UIView?
会导致它消失。
这取决于您采用这两种实现路径中的哪一种,但这应该足以为您指明正确的方向。
编辑:
根据您添加的代码,您似乎是在 viewForHeaderInSection
内部调用 yourTableViewInstance.dequeueReusableCell(withIdentifier:for:)
而不是 yourTableViewInstance.dequeueReusableHeaderFooterView(withIdentifier:)
。
您需要有UITableViewHeaderFooterView
的子类,然后正确调用它。创建新的子类,然后更改:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
let cellHeader = tableViewHome.dequeueReusableCell(withIdentifier: "header") as! HeaderTableViewCell
// ...
到这里:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
let cellHeader = tableViewHome.dequeueReusableHeaderFooterView(withIdentifier: "header") as! HeaderTableView
// ...
您需要在此处执行两个步骤:
-
创建一个新类,继承
UITableViewHeaderFooterView
而不是 UITableViewCell
。
然后使用上述适当的类。
【讨论】:
我更新了我的问题,请再次查看。谢谢 已更新以反映。看起来您正在混淆单元格和页眉/页脚视图。在正确的轨道上,但几乎就在那里! 您好,很抱歉回复晚了,好吧,如果我使用yourTableViewInstance.dequeueReusableHeaderFooterView(withIdentifier:)
,那么我将无法访问按钮,如果可能的话,任何帮助都将是可观的。谢谢。
感谢您的帮助,我做到了。谢谢:)
我在这里有点困惑。似乎答案匹配与问题不匹配,尽管它确实符合 OP 的要求。具体来说,问题是如何重新加载单个/特定的 Header 单元格。答案指出了使用UITableViewHeaderFooterView
的“正确”方式,但没有回答如何使用该方法重新加载单个/特定标头。我假设目标是找到reloadSectionIndexTitles()
,但只针对单个部分。 [尽管 Apple 的文档说“重新加载表格视图右侧索引栏中的项目”。这令人困惑。]【参考方案2】:
是的,是的。
假设这是你的方法的实现:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
let customCell = .... as! YourCustomCell
customCell.someLabel.text = "Some Data"
//... filling your curstom cell
return customCell
你可以这样改
func updateHeaderView(headerView:YourCustomCell, section: Int)
customCell.someLabel.text = "Some Data"
//... filling your curstom cell
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
let customCell = .... as! YourCustomCell
self.updateHeaderView(customCell, section)
return customCell
然后随时再次致电self.updateHeaderView(customCell, section)
,例如
func buttonClicked()
let customCell = self.tableView.headerView(forSection: 0) as! YourCustomCell
self.updateHeaderView(customCell, 0)
【讨论】:
在let customCell = tableViewHome.headerView(forSection: 0) as! HeaderTableViewCell
中写着Cast from 'UITableViewHeaderFooterView?' to unrelated type 'HeaderTableViewCell' always fails
【参考方案3】:
我认为您的标题视图类正在扩展 UITableViewHeaderFooterView 类。在扩展中添加一个函数
extension UITableViewHeaderFooterView
func reloadHeaderCell()
preconditionFailure("This method must be overridden")
现在在您的 Header 类中覆盖它,如下所示
class HeaderView: UITableViewHeaderFooterView
override func reloadHeaderCell()
////// add your logic to reload view
现在您可以简单地调用下面的行来刷新视图
self.tableView?.headerView(forSection:0)?.reloadHeaderCell()
【讨论】:
【参考方案4】:我做了什么并且工作非常正确,请按照给定的答案:
SWIFT 3.1
第 1 步:
首先我拿了一个view
xib,根据我的要求设计了它,并在我要求的课程中注册了。
其次,做了UITableViewHeaderFooterView
的子类class HeaderView: UITableViewHeaderFooterView
如下图:
在我的必修课(这里是 homeclass)中,我确实为我的 tableview 注册了我的 xib
文件。
override func viewDidLoad()
super.viewDidLoad()
tableViewHome.register(UINib(nibName: "HeaderView", bundle: nil), forHeaderFooterViewReuseIdentifier: "HeaderView")
第 2 步:
然后在我的必修课中,我做了以下操作:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
let cellHeader = tableViewHome.dequeueReusableHeaderFooterView(withIdentifier: "HeaderView") as! HeaderView
cellHeader.filterAction(cellHeader.filter1Btn)
return cellHeader
它开始按照我的要求工作,后来我为我的班级中的更多动作添加了自定义委托,但是通过子视图,它现在可以工作了。
【讨论】:
以上是关于在 UITableView 中仅重新加载一个节标题的主要内容,如果未能解决你的问题,请参考以下文章
重新加载 UITableView 而不重新加载 Section Header