Slide 1

Slide 1 text

iOS Accessibility Done Right...

Slide 2

Slide 2 text

Agenda • iOS Accessibility overview • VoiceOver demo • UIAccessibility & UIAccessibilityContainer • Some code + demo • Tips • Questions

Slide 3

Slide 3 text

It’s really simple

Slide 4

Slide 4 text

iOS Accessibility • Zoom. 
 Magnifies the entire device screen. • White on Black.
 Inverts the colors on the display. • Mono Audio.
 Combines the sound of the left and right channels into a mono signal played on both sides. • Speak Auto-text.
 Speaks the text corrections and suggestions iPhone makes while users type. • Voice Control.
 Allows users to make phone calls and control iPod playback using voice commands.

Slide 5

Slide 5 text

VoiceOver • Screen reading technology • Intermediary between UI and user touch • Provides descriptions of elements and actions • Prevents accidents by describing what the user can do, is about to do and what results to expect

Slide 6

Slide 6 text

VoiceOver • Label - A succinct label that identifies the accessibility element. • Value - The value of the accessibility element. • Hint - A brief description of the result of performing an action on the accessibility element. • Etc..

Slide 7

Slide 7 text

Why the extra effort? • Increases user base • Allows app usage without seeing the screen • Might be a strict requirement • It’s just the right thing to do

Slide 8

Slide 8 text

VoiceOver demo

Slide 9

Slide 9 text

UIAccessibility & UIAccessibilityContainer • Most important objects to get to know when implementing accessibility • Every UIControl implements UIAccessibility • Want something custom? Implement the UIAccessibilityContianer protocol.

Slide 10

Slide 10 text

UIAccessibility • Informal protocol • Allows objects to report their accessibility status • Reports accessibility information: label, value and hint. • Also allows reporting of other meta data: trait, frame, activationPoint

Slide 11

Slide 11 text

UIAccessibility - (NSString *)accessibilityLabel ! - (NSString *)accessibilityValue ! - (NSString *)accessibilityHint

Slide 12

Slide 12 text

- (NSString *)accessibilityHint { return @"Over te maken bedrag"; } ! - (NSString *)accessibilityLabel { return @"Bedrag"; } ! - (NSString *)accessibilityValue { NSString *value = [super accessibilityValue]; if (value != nil && value.length > 0) return [NSString stringWithFormat:@"€ %@", value]; else return nil; }

Slide 13

Slide 13 text

[button setAccessibilityValue: [NSString stringWithFormat:@"%@ %@ %@", statusText, self.title, self.accountNumberLabel.accessibilityLabel]]; [button setAccessibilityTraits:UIAccessibilityTraitNone]; [button setAccessibilityHint: NSLocalizedString(@"Dubbelklik om zichtbaarheid te wijzigen.", @"Account cell: hide button accessibility hint")];

Slide 14

Slide 14 text

What about traits? • Traits signify meta data about the object being made accessible. • Two types • What is it?
 UIAccessibilityTraitButton, UIAccessibilityTraitLink, UIAccessibilityTraitImage, etc • What state does it have?
 UIAccessibilityTraitNotEnabled, UIAccessibilityTraitUpdatesFrequently


Slide 15

Slide 15 text

- (void) checkBoxButtonPressed:(id)sender { UIButton * const checkBoxButton = sender; if(self.isCheckBoxSelected) { ! checkBoxButton.accessibilityTraits = UIAccessibilityTraitButton; ! [checkBoxButton setImage: self.checkBoxImage forState:UIControlStateNormal]; self.checkBoxSelected = FALSE; } else { ! checkBoxButton.accessibilityTraits = UIAccessibilityTraitButton | UIAccessibilityTraitSelected; ! [checkBoxButton setImage: self.checkBoxSelectedImage forState:UIControlStateNormal]; self.checkBoxSelected = TRUE; } }

Slide 16

Slide 16 text

Traits • UIAccessibilityTraitSummaryElement
 Read when the view appears. • The state related traits should be changed when the relevant UI state changes. • Every trait on an object will have some impact on VoiceOver

Slide 17

Slide 17 text

UIAccessibility Container • Informal protocol • Allows a UIView subclass to make any number of objects it contains accessible

Slide 18

Slide 18 text

UIAccessibility Container -(BOOL)isAccessibilityElement
 Should return NO when implementing the container protocol ! - (NSInteger)accessibilityElementCount ! - (id)accessibilityElementAtIndex:(NSInteger)index Returns a UIAccessibilityElement ! - (NSInteger)indexOfAccessibilityElement:(id)element

Slide 19

Slide 19 text

// Returns NO because we are implementing the informal protocol. -(BOOL)isAccessibilityElement { return NO; } ! - (NSInteger)accessibilityElementCount { return accessibleElements.count; } ! - (id)accessibilityElementAtIndex:(NSInteger)index { UIAccessibilityElement *element = [accessibleElements objectAtIndex:index]; return element; } ! - (NSInteger)indexOfAccessibilityElement:(id)element { // Returns accessibleElements is an NSArray filled with accessibility elements return [accessibleElements indexOfObject:element]; }

Slide 20

Slide 20 text

• Returned from the UIAccessibilityContainer protocol accessibilityElementAtIndex: message. • Implements the UIAccessibility protocol • Proxy for screen elements which do not have their own VoiceOver, i.e: Custom drawing, Table cell accessory views • Warning: The frame value should be defined in screen coordinates UIAccessibilityElement

Slide 21

Slide 21 text

Accessibility notifications • Use UIAccessibilityPostNotification () • UIAccessibilityAnnouncementNotification • UIAccessibilityLayoutChangedNotification • UIAccessibilityScreenChangedNotification

Slide 22

Slide 22 text

- (void) checkBoxButtonPressed:(id)sender { UIButton * const checkBoxButton = sender; if(self.isCheckBoxSelected) { ! checkBoxButton.accessibilityTraits = UIAccessibilityTraitButton; ! if (UIAccessibilityIsVoiceOverRunning()) { UIAccessibilityPostNotification( UIAccessibilityAnnouncementNotification, NSLocalizedString(@"Contact wordt niet toegevoegd aan uw adresboek", @"")); } [checkBoxButton setImage: self.checkBoxImage forState:UIControlStateNormal]; self.checkBoxSelected = FALSE; } else { ! checkBoxButton.accessibilityTraits = UIAccessibilityTraitButton | UIAccessibilityTraitSelected; ! if (UIAccessibilityIsVoiceOverRunning()) { UIAccessibilityPostNotification( UIAccessibilityAnnouncementNotification, NSLocalizedString(@"Contact wordt toegevoegd aan uw adresboek", @"")); } [checkBoxButton setImage: self.checkBoxSelectedImage forState:UIControlStateNormal]; self.checkBoxSelected = TRUE; } }

Slide 23

Slide 23 text

Tips • Convert a view coordinates to a screen coordinates ! • Set the frame when VoiceOver calls the accessibilityElementAtIndex: message CGRect frame = [self.contentView convertRect:frame toView:window]; frame = [window convertRect:frame toView:nil];