I found out, that even though I could set accessibilityLabel
of UISegmentedControl
's segment (see: How do I set the accesibility label for a particular segment of a UISegmentedControl?), I couldn't set accessibilityIdentifier
, which was equally important for my project. I need to target a segment irrespective of its text and accessibilityLabel
for automation purposes.
For example, the code:
NSString *name = [NSString stringWithFormat:@"Item %li", (long)idx];
segment.accessibilityIdentifier = name;
NSLog(@"ID: %@", segment.accessibilityIdentifier);
results in:
ID: (null)
No exceptions are thrown.
Does anybody have insight into why accessibilityLabel
is implemented, but not accessibilityIdentifier
?
Here is an example of looping through the views to set the accessibilityIdentifier by referencing the segment title.
Unfortunately when you set the identifier it doesn't persist. UISegment
s must be doing some tricky overriding. Still at a loss for how to get this to work.
extension UISegmentedControl {
/// Sets accessibility for segment buttons
func setAccessibilityIdentifier(_ accessibilityIdentifier: String, for segmentTitle: String) {
guard let segment = subviews.first(where: {
$0.subviews.contains(where: { ($0 as? UILabel)?.text == Optional(segmentTitle) })
}) else { return }
segment.accessibilityIdentifier = accessibilityIdentifier
}
}
I got around this issue by writing a Swift extension for XCUIElement
that added a new method tap(at: UInt)
. This method gets the buttons
query of the element and sort the results based on their x position. This allows us to specify which segment of the UISegmentedControl
we want to tap rather than relying on the button text.
extension XCUIElement {
func tap(at index: UInt) {
guard buttons.count > 0 else { return }
var segments = (0..<buttons.count).map { buttons.element(boundBy: $0) }
segments.sort { $0.0.frame.origin.x < $0.1.frame.origin.x }
segments[Int(index)].tap()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With