1

I'm adding accessibility to my iOS app. I'm seeing a specific situation that when I tap on a UIView that has isAccessibilityElement = false, and all of its ancestor views are also isAccessibilityElement = false, VoiceOver will speak the text from this view's sibling - a different child of this view's parent. And in Accessibility Inspector, when I hover over this view, the sibling lights up.

I don't understand how some view that's not in the hierarchy of the one I'm tapping on could be used for VoiceOver text. I don't see any behavior like this documented for iOS 11. How could this be happening?

Edit: I've created a simple project with a UITableView, containing UITableViewCell objects, each of which contains a UILabel. Tapping on a UITableViewCell (outside the UILabel) will read the UILabel within it. How do I disable that behavior, so that only tapping on the label itself, not on its containing UITableViewCell, will read the label?

Brian Kendig
  • 2,452
  • 2
  • 26
  • 36
  • @XLE_22 I'm sorry, but it didn't answer the question. I was asking about a situation where _nothing_ in that particular view's hierarchy was an accessible element, and iOS would choose to read something outside the hierarchy. You described a situation where _more than one_ view in a hierarchy is an accessible element and how to get a specific view to be spoken. – Brian Kendig Mar 30 '22 at 20:00
  • Indeed, I didn't understand your problem at all... you should have told me before. ‍ After reading your edit, I thought you wanted to have only the label of a cell to be vocalized when selected (the cell wouldn't be accessible). However, your initial situation sounds like a modal view or phantom elements: more information about the structure of your view hierarchy would be welcome if need be. – XLE_22 Mar 31 '22 at 08:24

1 Answers1

1

A table view cell (container) and its content (children) cannot be accessible all together (explanation here).

Follow the steps hereunder to answer your edit mention so that only tapping on the label itself, not on its containing UITableViewCell, will read the label.

  • Create your own UITableViewCell class including one label.

    class TestTableViewCell: UITableViewCell {
    
        @IBOutlet weak var myLabel: UILabel!
    
        override var accessibilityTraits: UIAccessibilityTraits {
            get { return UIAccessibilityTraitNone }
            set {}
        }
    }
    
  • Define your label as a UIAccessibilityElement in the cell implementation to be included in its accessibilityElements array.

    func tableView(_ tableView: UITableView,
                   cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
            let zeCell = tableView.dequeueReusableCell(withIdentifier: "myPersoCell",
                                                       for: indexPath) as! TestTableViewCell
    
            zeCell.accessibilityElements = nil
    
            var elements = [UIAccessibilityElement]()
    
            let contentA11yElt = UIAccessibilityElement(accessibilityContainer: zeCell)
            contentA11yElt.accessibilityTraits = UIAccessibilityTraitStaticText
            contentA11yElt.accessibilityFrameInContainerSpace = zeCell.contentLabel.frame //To be adapted
            contentA11yElt.accessibilityLabel = "label content"
    
            elements.append(contentA11yElt)
            zeCell.accessibilityElements = elements
    
            return zeCell
        }
    

Following these code snippets will allow to select a label located inside a table view cell and to read out its content as desired.

XLE_22
  • 5,124
  • 3
  • 21
  • 72