How can I set accessibilityIdentifier to UIAlertController?

前端 未结 4 1636
梦毁少年i
梦毁少年i 2021-02-05 05:56

This is how I simply create UIAlertController and present it on the screen:

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


        
4条回答
  •  醉梦人生
    2021-02-05 06:29

    The only way I figured out to do this was to use Apple's private APIs. You call valueForKey on the UIAlertAction object with this super secret key: "__representer" to get whats called a _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"
        })
    

    This has to be done in the completion handler because that that _UIAlertControllerActionView won't exist until the view is presented. On a side note in my project I used these following extensions to make things easier / more readable:

    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
        }
    }
    

    So the above code would be rewritten:

        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()
        })
    

    My first attempt involved trying to navigate the view hierarchy but that became difficult since UIAlertControllerActionView was not a part of the public API. Anyway I'd probably would try to ifdef out the valueForKey("__representer") for builds submitted for the app store or Apple might give you a spanking.

提交回复
热议问题