Here is my code:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return self.setupFriendsHeaderView()
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
view.accessibilityTraits = .none
for subView in view.subviews {
subView.accessibilityTraits = .none
}
}
func setupFriendsHeaderView() -> UIView? {
let view = UIView(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: tableView.frame.width, height: 44)))
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.switchPendingRequestsStatus)))
view.isAccessibilityElement = true
view.accessibilityLabel = "Pending requests"
return view
}
When you tap the header first time VoiceOver says: "Pending requests. Pending requests header." Sometimes it doesn't manage to finish the first sentence and starts speaking the next one. The second time it just says "Pending requests header." What I need it to do is say "Pending requests" once, and no word "heading".
I saw the answer recommending to use willDisplayHeaderView
method, but it doesn't help at all.
If you want to display a table view with section headers using VoiceOver never saying "header", just forget it: that's a dead end ⟹ there's currently no solution to complete this kind of table view design.
The best way to get your technical purpose is to create a single table view whose section headers are single cells with a different appearance ⟹ I specified "technical" because, functionally, that's definitely neither appropriate nor recommended for the VoiceOver users.
Indeed, the section headers are important markers that not only delimit specific blocks of information but also allow to move very quickly from one section to another thanks to the rotor.
I guess your purpose might be purely visual because, functionally speaking, it can't be approved by any accessibility experts or VoiceOver users.
As you did, I spent a lot of time to try and find a technical solution for this "problem" but, even if I found it (unfortunately I didn't), I would never have implemented it for sure.
========== EDIT ==========
After your comment (07.25.2019), I now understand that your problem is the title that is read twice and not the will of removing the 'header' trait.
I created a blank project where I implemented the code snippet hereunder to get a tableview with headers that are never repeated twice:
class SimpleHeadersTableViewController: UITableViewController {
override func numberOfSections(in tableView: UITableView) -> Int { return 4 }
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 5 }
override func tableView(_ tableView: UITableView,
viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRect(origin: CGPoint.zero,
size: CGSize(width: tableView.frame.width,
height: 44)))
let a11yHeader = UIAccessibilityElement(accessibilityContainer: headerView)
a11yHeader.accessibilityFrameInContainerSpace = headerView.frame
a11yHeader.isAccessibilityElement = true
a11yHeader.accessibilityLabel = "Pending requests"
a11yHeader.accessibilityTraits = .header
headerView.accessibilityElements = [a11yHeader]
return headerView
}
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId",
for: indexPath)
cell.textLabel?.text = String(indexPath.row)
return cell
}
}
Try this out and adapt it to your application.
Now, VoiceOver reads table header once and always adds the word “heading”.