如何将accessibilityIdentifier设置为UIAlertController?

这就是我简单地创建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"] 

可能吗?

我想出这样做的唯一方法是使用Apple的私有API。 您可以使用此超级密钥在UIAlertAction对象上调用valueForKey"__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可能会给你打屁股。

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

我能够像这样设置可访问性标识符:

 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) 

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

它当然不是完美的,但它起作用 – 至少对我使用Appium进行测试。

来自Apple文档……

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

使警报视图可访问

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