Reputation: 29
I have a UITableView with infinite cells, these are loaded as you scroll down. And I also have a floating button at the bottom. VoiceOver reads the cells one by one, the problem is that as new cells are loaded, the button is never reached. I would like VoiceOver to treat the table as a group, to access and go through its elements and to be able to exit to go to the button. What I want is something similar to what the mail app currently does.
I'm working with UIKit in Swift.
I've tried setting the UITableView
with the isAccessibilityElement
flag to true
but it doesn't seem to affect anything. I have also tried with the accessibilityContainerType
setting it to .semanticGroup
.
The accessibilityLabel
to the UITableView
does read it when it enters the first cell.
Upvotes: 0
Views: 423
Reputation: 5671
You followed the appropriate path by using the accessibilityContainerType
property with the .semanticGroup value but I think you wrote it only for the table view. š³
To move from one group to another, this property should be inserted to each of the desired elements.
I reproduced your environment under Xcode 14 and iOS 16.4 using UIKit
and the storyboard.
I implemented this property to the label, the table view and the button so as to make VoiceOver understand that three different groups of elements may be selected:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var myLabel: UILabel!
@IBOutlet weak var myTableView: UITableView!
@IBOutlet weak var myButton: UIButton!
let maxCells = 100
override func viewDidLoad() {
super.viewDidLoad()
myLabel.accessibilityContainerType = .semanticGroup
myTableView.accessibilityContainerType = .semanticGroup
myButton.accessibilityContainerType = .semanticGroup
myTableView.delegate = self
myTableView.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
myTableView.headerView(forSection: 0)?.accessibilityFrame = myTableView.frame
myTableView.headerView(forSection: 0)?.accessibilityLabel = "HERE IS THE TABLE VIEW"
}
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int { return maxCells }
func tableView(_ tableView: UITableView,
titleForHeaderInSection section: Int) -> String? { return "THE TABLE VIEW TITLE" }
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let myCell = myTableView.dequeueReusableCell(withIdentifier: "myCell",
for: indexPath)
var config = myCell.defaultContentConfiguration()
config.text = "Table view cell nĀ° \(indexPath.row)"
myCell.contentConfiguration = config
return myCell
}
}
Next, follow the steps below to understand the proper gestures for reaching your goal with VoiceOver:
Containers
item.You can now consider your table view as a group and get out of it without scrolling all the cells inside with VoiceOver. ššŖš
ā ļø EDIT 2023/09/04 ā ļø
I've finally understood the way you got this use case. š„³
To get this specific behavior, you use the Navigation Style mode available in the settings (through the rotor as well) since iOS 15:
When developing, this API
is only available for the Switch Control
and can be embedded in an app this way but it's impossible with VoiceOver
for which Apple uses this property as private.
Switch Control uses this technology, but VoiceOver and other assistive technologies do not.
Moreover, there's no notification to be aware of the Navigation Style
mode. š
Finally, if you want to reach a behavior like the native mail app with VoiceOver in iOS 16 with UIKit
, the only way is to use the containers as described in my initial answer. š
Upvotes: 2