Reload only one section title in UITableView
I am using a custom cell as the section heading in UITableView
. There are three buttons in this cell. If any of the buttons is pressed in this section cell, it should only reload that custom section cell, not any rows. Is it possible?
I used the following code to reload this cell:
tableViewHome.reloadSections([1], with: UITableViewRowAnimation.none)
It hides my section cell and mangles my entire table.
UPDATE
I am using UITableView
and the following code which I am using:
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)
}
source to share
I'm a bit confused about what's going on here, but it looks like it makes sense here UITableView
:
UITableView
has its own cell concept, implemented as UITableViewCell
its own header / footer concept, implemented as UITableViewHeaderFooterView
.
Depending on which of the two you had in mind, there are several things you can do to get the intended effect:
Approach UITableViewCell
:
If you are using UITableViewCell
as the first line of a section to act as a "title" and you just want to reload that line, excluding the rest of the section, you can call yourTableViewInstance.reloadRows(at:with:)
(Apple Documentation) This method takes an IndexPath
s array and an animation style. You can pass to indexPath the one you want to reload.
Approach UITableViewHeaderFooterView
:
If you are using the correct one UITableViewHeaderFooterView
, you need to make sure you provide the appropriate view when you reload the section. Zach Shapiro describes the steps to be taken in this answer :
- Create a class that is a subclass
UITableViewHeaderFooterView
. - Register it with an instance
UITableView
. - Then in
viewForHeaderInSection
you dolet header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderView") as! YourHeaderViewSubclass
The last thing he points out is this:
The deceptive thing is a function that calls back
UIView?
when it really needs itdequeuedReusableHeaderFooterView
orreloadData
, which will cause it to disappear.
It depends on which of these two implementation paths you take, but this should be enough information to point you in the right direction.
Edit:
Based on the code you added, it looks like you are calling yourTableViewInstance.dequeueReusableCell(withIdentifier:for:)
instead yourTableViewInstance.dequeueReusableHeaderFooterView(withIdentifier:)
inside viewForHeaderInSection
.
You must have a subclass UITableViewHeaderFooterView
and then call it correctly. Create this new subclass and then change this:
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
// ...
You need to follow these two steps:
- Create a new class by subclassing
UITableViewHeaderFooterView
instead ofUITableViewCell
. - Then use the appropriate class as described above.
source to share
Yes it is.
Let's say this is the implementation of your method:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let customCell = .... as! YourCustomCell
customCell.someLabel.text = "Some Data"
//... filling your curstom cell
return customCell
}
You can change it this way
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
}
And call again self.updateHeaderView(customCell, section)
when you want, eg.
func buttonClicked() {
let customCell = self.tableView.headerView(forSection: 0) as! YourCustomCell
self.updateHeaderView(customCell, 0)
}
source to share
What I have done and is working very correctly, Please follow the given answer:
SWIFT 3.1
Step 1:
First, I took a view
xib designed according to my requirement and registered in my class.
Second, did the subclass class HeaderView: UITableViewHeaderFooterView
forUITableViewHeaderFooterView
Like the following image:
In my required class (homeclass here), I registered my file xib
for my view in the table.
override func viewDidLoad() {
super.viewDidLoad()
tableViewHome.register(UINib(nibName: "HeaderView", bundle: nil), forHeaderFooterViewReuseIdentifier: "HeaderView")
}
Step 2:
Then in my required class I did the following:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cellHeader = tableViewHome.dequeueReusableHeaderFooterView(withIdentifier: "HeaderView") as! HeaderView
cellHeader.filterAction(cellHeader.filter1Btn)
return cellHeader
}
And it started working as per my requirement, later I added a custom delegate for more actions in my class, but through subviewing, now it works.
source to share
I think your header view class extends the UITableViewHeaderFooterView class. Add function to extension
extension UITableViewHeaderFooterView{
func reloadHeaderCell(){
preconditionFailure("This method must be overridden")
}
}
Now override this in your header class as shown below
class HeaderView: UITableViewHeaderFooterView {
override func reloadHeaderCell() {
////// add your logic to reload view
}
}
Now you can just call below line to update the view
self.tableView?.headerView(forSection:0)?.reloadHeaderCell()
source to share