Pergunta

It will probably be obvious, but I have never done any work with NSAccessibility before so I'm assuming what I'm asking is something simple I've overlooking.

I have an NSTextField displaying a duration like this, 15:39. This text field is a subview of an NSTableCellView in a view-based NSTableView.

When VoiceOver is enabled, it currently reads off, "one five, three nine", which seems completely useless. Instead, I want it to say "Duration is 15 minutes, 39 seconds."

I can produce the desired string, but I cannot figure out which accessibility attributes I have to set to make this happen.

I've tried setting the accessibility description in IB, which has no effect (whether setting it on the NSTextField or NSTextFieldCell).

I've also tried overriding accessibilityValue: and accessibilityAttributeValue:forParameter: in order to provide custom attribute values for:

  • NSAccessibilityNumberOfCharactersAttribute
  • NSAccessibilityStringForRangeParameterizedAttribute
  • NSAccessibilityAttributedStringForRangeParameterizedAttribute
  • NSAccessibilityStringForRangeParameterizedAttribute.

This seemed to be the right track since that does allow me to replace what is read aloud by voice over, however, providing any NSRange for NSAccessibilityVisibleCharacterRangeAttribute that doesn't match the length of the "15:39" string causes voice over to completely skip this field when reading off the NSTableCellView's contents. So, the best I've been able to do is get Voice over to say "Durat" instead of reading off "15:39" :(

Everything I've tried, I've tried on NSTextField and NSTextFieldCell.

Ideally, I'd prefer to do what I'd do in iOS and just set the accessibilityLabel of the NSTableCellView, but I see no reasonable way of doing this in AppKit. Hopefully I'm just missing something.

Foi útil?

Solução

I was able to achieve this simply by setting accessibilityValueDescription on the NSTextField. This method is part of the new Accessibility API on OS X 10.10 and higher. With the older API, you may be able to use kAXValueDescriptionAttribute to achieve the same thing.

Outras dicas

The solution for overriding the text read by Voice Over was much simpler than I thought. All I had to do was override the value returned for NSAccessibilityAttributedStringForRangeParameterizedAttribute:

// The displayed text for this text field is "45m".
// The voice over for this field incorrectly reads "forty five meters" instead of "forty five minutes".  
// The following forces it to read "Duration forty five minutes"

-(id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter {
return ([attribute isEqualToString:NSAccessibilityAttributedStringForRangeParameterizedAttribute])
        ? [[NSAttributedString alloc] initWithString:@"Duration: 45min"];
        : [super accessibilityAttributeValue:attribute forParameter:parameter];
}

I believe I've answered my own question, at least enough to control what's read off when clicking a table cell view.

By overriding accessibilityIsIgnored to return "NO" in my NSTableCellView sub-class I was able to specify exactly what I wanted to be read off for the table cell by overriding the NSAccessibilityTitleAttribute for the cell. I had not tried this before b/c I had misunderstood the purpose of the accessibilityIsIgnored selector.

From the documentation for accessibilityIsIgnored:

When asking for an object’s children, ignored children should not be included; instead, the ignored children should be replaced by their own unignored children.

I'd like to be able to control exactly what is read off for the individual NSTextFields in the future, but controlling what is read off for an entire NSTableCellView is actually ideal for my particular situation.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top