无法设置UISegmentedControl的段的accessibilityIdentifier

时间:2014-04-04 21:41:32

标签: ios ios-ui-automation

我发现,即使我可以设置accessibilityLabel段的UISegmentedControl(请参阅:How do I set the accesibility label for a particular segment of a UISegmentedControl?),我也无法设置accessibilityIdentifier,这是对我的项目同样重要。我需要定位一个段而不管其文本和accessibilityLabel用于自动化目的。

例如,代码:

NSString *name = [NSString stringWithFormat:@"Item %li", (long)idx];
segment.accessibilityIdentifier = name;
NSLog(@"ID: %@", segment.accessibilityIdentifier);

结果:

ID: (null)

不会抛出异常。

是否有人了解accessibilityLabel实施的原因,而不是accessibilityIdentifier

6 个答案:

答案 0 :(得分:2)

我通过为XCUIElement编写了一个添加了新方法tap(at: UInt)的Swift扩展来解决这个问题。此方法获取元素的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()
    }
}

答案 1 :(得分:0)

我使用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

然后我在@[@"0", @"1"]初始化中用@[@"", @""]替换了UISegmentedControl,代码适用于所有提到的平台。

看来,accessibilityIdentifieraccessibilityLabel都已实现,但不知何故UISegmentedControl的初始值会干扰其accessibilityIdentifier段。

答案 2 :(得分:0)

我实施了这种解决方法并实现了自动化(使用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)
}

答案 3 :(得分:0)

我只有图像,没有任何标签,所以我使用下面的代码。我发现索引与屏幕上的顺序不对应,因此我键入了初始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
        }
    }
}

答案 4 :(得分:0)

我遇到了这个。先前的某些答案似乎根本没有解决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
            }
        }
    }
}

答案 5 :(得分:0)

这里是循环浏览视图以引用段标题来设置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
    }

}