簡體   English   中英

無法設置 UISegmentedControl 的段的 accessibilityIdentifier

[英]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"]替換為@[@"", @""] ,該代碼適用於所有提到的平台。

看來, accessibilityIdentifieraccessibilityLabel均已實現,但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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM