Making a programmatic iOS UIView fully accessible
I am programmatically building a UINavigationContoller
for iOS and am having problems making it fully accessible. In loadView
I create the main UIView
and set it as NOT accessible:
- (void)loadView
{
CGRect viewRect = [[UIScreen mainScreen] applicationFrame];
UIView *tmp = [[UIView alloc] initWithFrame:viewRect];
[tmp setIsAccessibilityElement:NO];
I then add additional UIViews
that contain just background images and also set those as not accessible. All views and controls are added onto the "tmp" UIView
created above. Here is a "background" view example:
UIImage* microphone = [UIImage imageNamed:@"microphone.jpg"];
UIView* microphoneView = [[[UIView alloc] initWithFrame: CGRectMake(0,0,viewRect.size.width, microphone.size.height)] autorelease];
[microphoneView setBackgroundColor:[UIColor colorWithPatternImage:microphone]];
[microphoneView setIsAccessibilityElement:NO];
[tmp addSubview:microphoneView];
Finally I add a UIButton
, UILabel
and UIButtonBarItem
. I add these last so they are on the top of the view hierarchy. I add accessibility labels and traits to them. Here is the UIButton
:
self.recordImage = [UIImage imageNamed: @"record_button.png"];
self.stopRecordImage = [UIImage imageNamed: @"stop_button.png"];
self.recordButton.accessibilityTraits |= UIAccessibilityTraitStartsMediaSession;
self.recordButton = [[UIButton alloc ] initWithFrame: CGRectMake((viewRect.size.width - recordImage.size.width)/2 , (microphone.size.height + (grayBkg.size.height - recordImage.size.height)/2), recordImage.size.width, recordImage.size.height)];
[self.recordButton setIsAccessibilityElement:YES];
[self.recordButton setAccessibilityLabel: @"toggle recording start"];
[self.recordButton setImage: recordImage forState:UIControlStateNormal];
[self.recordButton addTarget: self action:@selector(processButton:) forControlEvents:UIControlEventTouchUpInside];
[tmp addSubview:recordButton];
finally
....
[self setView:tmp];
[tmp release];
I did call UIAccessibilityPostNotification
(UIAccessibilityScreenChangedNotification
, nil); when I push this view onto the stack.
With voiceover on, when the view is displayed I can swipe and give each of my elements (the UIButtonBarItem
, UILabel
, and UIButton
) focus and I can activate them with double tap. However, VoiceOver speaks no information about the elements. Testing in the simulator with the Accessibility Inspector shows the labels I have set via aControl.accessibilityLabel = @"the label";
This view is used to record audio. If I activate the buttons and record the audio and stop recording, VoiceOver will now speak the labels for the elements when I focus them? Why is VoiceOver not speakin开发者_开发百科g the information when the view first loads? Any clues appreciated!
I am testing on an iPad 2 with iOS 4.3.3.
If you'd like your view to not be accessible, use:
[microphoneView setUserInteractionEnabled:NO];
This view is being used for audio recording. The problem was that I was setting the AVSession Category to AVAudioSessionCategoryRecord in the viewDidLoad method. This was causing VoiceOver not to speak the view information. I modified the code to set the category to AVAudioSessionCategoryRecord only when the record button is pushed. And I set it to AVAudioSessionCategoryPlayAndRecord when recording is finished. Here is the thread that explains it fully: http://lists.apple.com/archives/accessibility-dev/2011/Jul/msg00002.html
精彩评论