iOS Accessibility hide the "textField, double tap to edit" announcement

In Swift

let textField = UITextField()
textField.accessibilityTraits = UIAccessibilityTraitStaticText

*The example code in this answer was written and tested in Swift 3.

 

About the accessibilityTraits Property

The accessibilityTraits property is a UInt64 bitmask. UIKit includes named UInt64 constants such as UIAccessibilityTraitStaticText for ease in remembering which bits represent which settings.

When a UITextField is created, its accessibilityTraits property is set to "262144" which is "1000000000000000000" in binary. That means the 19th bit from the right signifies "text field". There is not a constant for this setting. I tried but could not figure out how to set the 19th bit to zero. This bit appears protected from editing by the implementation for UITextField. You could subclass UITextField and override the accessibilityTraits property to take full control of it like this...

Overriding accessibilityTraits

private var _accessibilityTraits: UInt64 = 0
override var accessibilityTraits: UInt64 {
    get {
        return _accessibilityTraits
    }

    set {
        _accessibilityTraits = newValue
    }
}

 

Using UIAccessibilityTraitStaticText

If the "text field" flag is on or "1" then VoiceOver will announce "text field". As @ChrisCM posted, if the "static text" flag is also on, it cancels out the "Text Field" flag and VoiceOver does not announce anything for the type of control.

The "static text" flag is set by adding decimal "64" doing a bitwise OR of binary "1000000" to the accessibilityTraits property. The UIAccessibilityTraitStaticText constant makes this value easy to remember.

This code illustrates what is happening:

Adding UIAccessibilityTraitStaticText to accessibilityTraits in detail

let textField = UITextField()
print("original textField.accessibilityTraits, binary: \(String(textField.accessibilityTraits, radix: 2)), decimal: \(textField.accessibilityTraits)")

print("UIAccessibilityTraitStaticText, binary: \(String(UIAccessibilityTraitStaticText, radix: 2)), decimal: \(UIAccessibilityTraitStaticText)")
textField.accessibilityTraits = UIAccessibilityTraitStaticText

print("modified textField.accessibilityTraits, binary: \(String(textField.accessibilityTraits, radix: 2)), decimal: \(textField.accessibilityTraits)")

Console Output:

original textField.accessibilityTraits, binary: 1000000000000000000, decimal: 262144
UIAccessibilityTraitStaticText, binary: 1000000, decimal: 64
modified textField.accessibilityTraits, binary: 1000000000001000000, decimal: 262208

 

|= Operator

The following also works. The |= operator takes the existing value and does a bitwise OR with "1000000". Since the original value of the UITextField accessibilityTraits is protected, this is not necessary.

textField.accessibilityTraits |= UIAccessibilityTraitStaticText

 

Assigning a Different Trait

To assign a different trait such as a "button", bitwise OR UIAccessibilityTraitButton like this:

textField.accessibilityTraits = UIAccessibilityTraitStaticText | UIAccessibilityTraitButton

print("modified textField.accessibilityTraits, binary: \(String(textField.accessibilityTraits, radix: 2)), decimal: \(textField.accessibilityTraits)")

Console Output:

modified textField.accessibilityTraits, binary: 1000000000001000001, decimal: 262209

In this case UIAccessibilityTraitStaticText cancels out "text field" while UIAccessibilityTraitButton adds "button"


Assuming your text field is a subclass of UITextField, you're looking for the static text trait.

UITextField* aTextField = .....
aTextField.accessibilityTraits |= UIAccessibilityTraitStaticText;