如何将accessibilityIdentifier设置为UIAlertController?

时间:2016-06-30 08:10:05

标签: ios swift accessibility

这就是我简单地创建UIAlertController并在屏幕上显示的方式:

private class func showAlertWithTitle(title: String, message: String) {

    let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
    //alert.accessibilityLabel = "my string here"      //doesnt work
    let action = UIAlertAction(title: "OK", style: .Default) { action in
        alert.dismissViewControllerAnimated(true, completion: nil)
    }

    alert.addAction(action)
    UIStoryboard.topViewController()?.presentViewController(alert, animated: true, completion: nil)
}

这就是我在 UITests

下访问它的方式
emailAlert = app.alerts["First Name"] //for title "First Name"

但是我想在那里设置自定义标识符并通过firstName进行访问:

emailAlert = app.alerts["firstName"]

有可能吗?

4 个答案:

答案 0 :(得分:6)

这是一个旧线程,但有人可能会使用它。

我能够像这样设置辅助功能标识符:

let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.view.accessibilityIdentifier = "custom_alert"
alert.view.accessibilityValue = "\(title)-\(message)"

alert.addAction(
    UIAlertAction(
        title: "ALERT_BUTTON_OK".localized,
        style: .default,
        handler: handler
    )
)

present(alert, animated: true)

这样我可以通过辅助功能标识符访问警报,并在辅助功能值中检查其内容。

当然不是很完美,但它确实有效 - 至少对我使用Appium进行测试。

答案 1 :(得分:5)

我想出这样做的唯一方法是使用Apple的私有API。您使用此超级密钥valueForKeyUIAlertAction对象上调用"__representer",以获取名为_UIAlertControllerActionView的内容。

    let alertView = UIAlertController(title: "This is Alert!", message: "This is a message!", preferredStyle: .Alert)
    let okAction = UIAlertAction(title: "OK", style: .Default, handler: nil)

    alertView.addAction(okAction)

    self.presentViewController(alertView, animated: true, completion: {
        let alertButton = action.valueForKey("__representer")
        let view = alertButton as? UIView
        view?.accessibilityIdentifier = "okAction_AID"
    })

这必须在完成处理程序中完成,因为在显示视图之前_UIAlertControllerActionView将不存在。在我的项目的旁注中,我使用以下扩展来使事情更容易/更易读:

extension UIAlertController {
    func applyAccessibilityIdentifiers()
    {
        for action in actions
        {
            let label = action.valueForKey("__representer")
            let view = label as? UIView
            view?.accessibilityIdentifier = action.getAcAccessibilityIdentifier()
        }

    }

}

extension UIAlertAction
{
    private struct AssociatedKeys {
        static var AccessabilityIdentifier = "nsh_AccesabilityIdentifier"
    }

    func setAccessibilityIdentifier(accessabilityIdentifier: String)
    {
        objc_setAssociatedObject(self, &AssociatedKeys.AccessabilityIdentifier, accessabilityIdentifier, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    }

    func getAcAccessibilityIdentifier() -> String?
    {
        return objc_getAssociatedObject(self, &AssociatedKeys.AccessabilityIdentifier) as? String
    }
}

所以上面的代码会被重写:

    let alertView = UIAlertController(title: NSLocalizedString("NMN_LOGINPAGECONTROLLER_ERROR_TITLE", comment: ""), message: message as String, preferredStyle:.Alert)
    let okAction = UIAlertAction(title: NSLocalizedString("NMN_OK", comment: ""), style: .Default, handler: nil)
    okAction.setAccessibilityIdentifier(InvalidLoginAlertView_AID)


    alertView.addAction(okAction)


    self.presentViewController(alertView, animated: true, completion: {
        alertView.applyAccessibilityIdentifiers()
    })

我的第一次尝试涉及尝试导航视图层次结构但由于UIAlertControllerActionView不是公共API的一部分而变得困难。无论如何,我可能会尝试为应用程序商店提交的版本valueForKey("__representer"),或Apple可能会给你打屁股。

答案 2 :(得分:0)

现在我有一个名为UIAlertAction的{​​{1}},我正在做:

addCamera

这使我可以在UI测试中点击它,如下所示:

addCamera.accessibilityLabel = "camera-autocomplete-action-photo"

答案 3 :(得分:-1)

来自Apple文档...

https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/UIKitUICatalog/UIAlertView.html

使警报视图可访问

默认情况下可以访问警报视图。 警报视图的可访问性与警报标题,警报消息和按钮标题有关。如果VoiceOver被激活,当显示警报时它会说出“警告”一词,然后说出其标题,然后是设置的消息。当用户点击按钮时,VoiceOver会说出其标题和单词“按钮”。当用户点击文本字段时,VoiceOver会说出其值和“文本字段”或“安全文本字段”。