![](/img/trans.png)
[英]How to set an accessibilityIdentifier on a UITabBar's buttons
[英]Unable to set accessibilityIdentifier of UISegmentedControl's segments
我發現,即使我可以設置UISegmentedControl
段的accessibilityLabel
(請參閱: 如何為 UISegmentedControl 的特定段設置可訪問性 label? ),我無法設置accessibilityIdentifier
,這對我的項目同樣重要. 出於自動化目的,我需要定位一個段,而不管其文本和accessibilityLabel
是什么。
例如,代碼:
NSString *name = [NSString stringWithFormat:@"Item %li", (long)idx];
segment.accessibilityIdentifier = name;
NSLog(@"ID: %@", segment.accessibilityIdentifier);
結果是:
ID: (null)
沒有異常被拋出。
是否有人了解為什么實施accessibilityLabel
而不是accessibilityIdentifier
?
通過為XCUIElement
編寫Swift擴展來解決此問題,該擴展添加了新方法tap(at: UInt)
。 此方法獲取元素的buttons
查詢,並根據其x位置對結果進行排序。 這使我們可以指定要點擊UISegmentedControl
哪個部分,而不是依賴按鈕文本。
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()
}
}
我已經使用Xcode 5.1.1和iOS Simulator 7.1測試了以下代碼:
UISegmentedControl *contol = [[UISegmentedControl alloc] initWithItems:
@[@"0", @"1"]];
[self.view addSubview:contol];
UIView *segment = [[contol subviews] firstObject];
segment.accessibilityIdentifier = @"Item 0";
NSLog(@"ID: %@", segment.accessibilityIdentifier);
它不適用於iPhone Retina (3.5-inch)
和iPhone Retina (4-inch)
即結果是:
ID: (null)
但它適用於iPhone Retina (4-inch 64-bit)
即結果為:
ID: Item 0
然后,我在UISegmentedControl
初始化中將@[@"0", @"1"]
替換為@[@"", @""]
,該代碼適用於所有提到的平台。
看來, accessibilityIdentifier
和accessibilityLabel
均已實現,但UISegmentedControl
的初始值會干擾其段的accessibilityIdentifier
。
我實現了此解決方法,並實現了自動化(使用KIF)。
代碼在Swift中,適用於Xcode 6.1.1,iOS 8 SDK
for index in 0..<segmentedControl.numberOfSegments {
let identifierView = UIView()
identifierView.accessibilityIdentifier = "Item \(index)"
(segmentedControl.subviews[index] as UIView).addSubview(identifierView)
}
我只有圖像,沒有任何標簽,因此我使用了下面的代碼。 我發現索引與屏幕上的順序不符,所以我鍵入了最初的accessibilityLabel
值,這些值是我在Interface Builder中指定的圖像的名稱。
override func viewDidLoad() {
super.viewDidLoad()
for segment in segmentedControl.subviews {
switch segment.accessibilityLabel {
case .Some("First Image"):
segment.accessibilityLabel = "Description of first item"
break
case .Some("Second Image"):
segment.accessibilityLabel = "Description of second item"
break
default:
NSLog("Unknown accessibility label: \(segment.accessibilityLabel)")
break
}
}
}
我遇到了這個。 先前的某些答案似乎根本沒有解決accessibilityIdentifier。 我確實嘗試了Jawwad訪問這些段並添加新的UIView並在其上設置accessibilityIdentifier的方法。 但是,我正在使用EarlGrey進行UI測試,但是不幸的是,當它嘗試點擊該視圖時,它不起作用。 但是,基於此,我做了以下DID工作的變體。
技巧是枚舉段(按照Jawwad的方法),然后為每個段找到UIImageView子視圖並設置其accessibilityID。 這適用於查找和交互。
let ids = ["Identifier1", "Identifier2"]
for index in 0..<segmentedControl.numberOfSegments {
if let view = p.subviews[index] as? UIView {
for v in view.subviews {
// Setting the ID twice would cause EarlGrey tests to fail
if let iv = v as? UIImageView, iv.accessibilityIdentifier == nil {
iv.accessibilityIdentifier = ids[index]
break
}
}
}
}
這是一個通過引用片段標題循環遍歷視圖以設置accessibilityIdentifier的示例。 不幸的是,當您設置標識符時,它不會持續存在。 UISegment
必須進行一些棘手的覆蓋。 對於如何使它起作用仍然不知所措。
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
}
}
我能夠通過覆蓋 UIView 的 NSArray *accessibilityElements 屬性並將 accessibilityIdentifier 添加到每個返回的 UISegment 來解決這個問題。
- (NSArray *)accessibilityElements {
NSArray *elements = [super accessibilityElements];
[elements enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {
obj.accessibilityIdentifier = self.identifiers[idx].accessibilityIdentifier;
}];
return elements;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.