13

I have a simple UIView hierarchy. There is a parent view A which contains view B and C. If I set all views as accessibility element, only view A is accessible. Views B and C are not clickable. I need all views (A, B and C) to be accessibility elements.

I know you can achieve that by putting all views (A, B and C) at the same level, but view hierarchy in my app does not allow any changes.

Do you have any solution for that?

Justin
  • 20,509
  • 6
  • 47
  • 58
pawel221
  • 977
  • 1
  • 7
  • 9

3 Answers3

7

Is view A an accessibility element? For subviews to be accessible, the containing view must not be an accessibility element.

view.isAccessibilityElement = false

If you need the third view, A, to be accessible, then make it a sibling view of B and C.

Justin
  • 20,509
  • 6
  • 47
  • 58
  • I couldn't make A sibling of B and C, as this was already the view hierarchy in my app, but I used parent view of A and UIAccessibilityContainer protocol to resolve my problem. Details of the solution you can find below in the answer. – pawel221 Aug 11 '16 at 09:29
7

1) Make all your views i.e A, B, C as accessibilityElement.

   A.isAccessibilityElement = true
   B.isAccessibilityElement = true
   C.isAccessibilityElement = true

2) If your parent view is parentView, then set all these views as its AccessibilityElements

parentView.accessibilityElements = [A, B, C]

PS :- accessibilityElements creates a group of all elements mentioned in array. This is also used to change the order of elements. But the only thing you have to keep in mind is to mention all the elements you have in parentView to this array otherwise the element will get skip while swiping on views.

Preeti Rani
  • 685
  • 7
  • 17
5

Finally I resolved it using UIAccessibilityContainer protocol and using my existing view hierarchy: A (parent), B (child) and C (child). I used another view, say X which was parent of A and implemented a UIAccessibilityContainer protocol in it. Here is example code of creation an array of UIAccessibilityElements which was created in view X.

- (NSArray *)voiceOverElements {
    if (!_voiceOverElements) {
        UIAccessibilityElement *element = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
        CGRect frame = UIAccessibilityConvertFrameToScreenCoordinates(A.frame, self);
        element.accessibilityFrame = frame;
        _voiceOverElements = @[element];
        for (UIView *view in A.subviews) {
            UIAccessibilityElement * element = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
            CGRect frame = UIAccessibilityConvertFrameToScreenCoordinates(view.frame, A);
            element.accessibilityFrame = frame;
            _voiceOverElements = [_voiceOverElements arrayByAddingObject:element];
        }
    }
    return _voiceOverElements;
}

In the same view (X), UIAccessibilityContainer protocol was implemented as follows:

- (BOOL)isAccessibilityElement {
    return NO;
}

- (id)accessibilityElementAtIndex:(NSInteger)index {
    return [self.voiceOverElements objectAtIndex:index];
}

- (NSInteger)accessibilityElementCount {
    return self.voiceOverElements.count;
}

- (NSInteger)indexOfAccessibilityElement:(id)element {
    return [self.voiceOverElements indexOfObject:element];
}
pawel221
  • 977
  • 1
  • 7
  • 9