UIPickerView Accessibility VoiceOver Issue

Viewed 141

When VoiceOver is enabled, voice-over for the UIPickerView always says “#Item 1 of #TotalNumberOfItems” no matter to which row we swipe. Programatically all the elements are getting updated with the correct selected index but the VoiceOver always says “#Item 1 of #TotalNumberOfItems”

Let me know if anyone came across this issue in PickerView?


Some Observations:

  1. If we leave the app for some time and then swipe, the index is voiced out correctly for once and then the same issue persists
  2. If we tap on the picker row after swiping, the index is voiced out correctly
  3. didSelect is called 2 times every time we swipe the row.
  4. DatePicker is working fine
  5. Default Reminder app has some PickerViews, voice-over works as expected. (Though found that index details are not proper when we scroll up and down) 

@implementation ViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.normalPicker.backgroundColor = [UIColor blackColor];
        self.categories = [[NSMutableArray alloc] initWithObjects:@"Apple", @"Bat", @"Cat", @"Dog", @"Elephant", @"Fish", @"Goat",@"Hen", nil];
    }
    
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
    {
        return 1;
    }
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
        return self.categories.count;
    }
    
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
        NSLog(@"DidSelect: Row = %@", self.categories[row]);
    }
    
    - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
        UILabel *label = nil;
        if (view == nil) {
            label = [UILabel new];
            label.adjustsFontSizeToFitWidth = NO;
            label.textAlignment = NSTextAlignmentCenter;
            label.textColor = [UIColor redColor];
        } else {
            label = (UILabel *) view;
        }
    
        NSString *text = self.categories[row];
        label.text = text;
        return label;
    }
    
    @end
1 Answers

Found a workaround for the same. Make an announcement including the index appending to the actual string.

-(void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{...
    UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, voiceOverText);
}
Related