iOS Accessibility Done Right... 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. 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 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.. 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 UIAccessibility & UIAccessibilityContainer • Most important objects to get to know when implementing accessibility • Every UIControl implements UIAccessibility • Want something custom? Implement the UIAccessibilityContianer protocol. 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 UIAccessibility - (NSString *)accessibilityLabel ! - (NSString *)accessibilityValue ! - (NSString *)accessibilityHint 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 - (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; } } 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 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 // Returns NO because we are implementing the <UIAccessibilityContainer> 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]; } • 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 Accessibility notifications • Use UIAccessibilityPostNotification () • UIAccessibilityAnnouncementNotification • UIAccessibilityLayoutChangedNotification • UIAccessibilityScreenChangedNotification