7

I have a UITabBarItem like so:

_Controller.tabBarItem = [[UITabBarItem alloc] initWithTitle:nil image:nil tag:0];

But having nil for a title removes the label needed for accessibility and KIF testing. An alternative I found is to set the title and move it off the screen, but that seems like a hacky solution:

_Controller.tabBarItem.title = @"Foo";
_Controller.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, 200);

Is it possible to have a UITabBarItem without a title, but still have an accessibility label?

EDIT to add full code for tab bar and background button code:

- (void) loadViewController {
    _Controller = [[UIViewController alloc] init];
    UIImage *normalImage = [UIImage imageNamed:@"bar.png"];
    UIImage *selectedTabImage = [UIImage imageNamed:@"barHover.png"];
    [self addCenterButtonWithImage:normalImage
                    highlightImage:selectedTabImage];

    _Controller.tabBarItem = [[UITabBarItem alloc] initWithTitle:nil image:nil tag:0];
}

// Create a custom UIButton and add it to the center of our tab bar
-(void) addCenterButtonWithImage:(UIImage*)buttonImage highlightImage:(UIImage*)highlightImage
{
    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
    [button setBackgroundImage:buttonImage forState:UIControlStateNormal];
    [button setBackgroundImage:highlightImage forState:UIControlStateHighlighted];
    [button addTarget:self action:@selector(openCamera) forControlEvents:UIControlEventTouchUpInside];

    button.center = CGPointMake(self.tabBar.frame.size.width/2.0, self.tabBar.frame.size.height/2.0 - 6.0);

    [self.tabBar addSubview:button];
}
wolffan
  • 1,084
  • 10
  • 15
jjj
  • 767
  • 2
  • 9
  • 14

2 Answers2

10

In iOS8, you can assign an accessibility label directly to a tab bar item:

_Controller.tabBarItem = [[UITabBarItem alloc] initWithTitle:nil image:nil tag:0];
_Controller.tabBarItem.accessibilityLabel = @"Foo";

For iOS7 and below, you are right that you need to do something to hide the text. You can force it offscreen like you had illustrated:

_Controller.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Foo" image:nil tag:0];
_Controller.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, 200);

Or you can make the text color clear:

_Controller.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Foo" image:nil tag:0];
[_Controller.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor clearColor]} forState:UIControlStateNormal];

Remember, whatever solution you come to will be used by visually impaired users to navigate you app. Since your background button is an unusable decoration, you should flag it as such:

button.isAccessibilityElement = NO;
button.userInteractionEnabled = NO;
Brian Nickel
  • 26,890
  • 5
  • 80
  • 110
  • 1
    This doesn't work for me. This seems to result in the button behind the UITabBarItem having an accessibility label set to its file name (without the extension) and not the label I set. It's also still behind the UITabBarItem and as such not tappable by KIF. EDIT: I guess I should've mentioned the UITabBarItem has an image behind it. – jjj Oct 14 '14 at 19:16
  • 1
    Hmm... It looks like accessibilityLabel works in iOS8 but not iOS7. How are you inserting the image behind the tab bar item? Can you tap the tab by using the file name as the accessibility label? – Brian Nickel Oct 14 '14 at 21:04
  • I've added the full code for the button to the original post. If I try to use the filename label I get the same error as when I try adding the label to the button inside `addCenterButtonWithImage`: `Accessibility element with label "bar" is not tappable. It may be blocked by other views.` Note that I didn't write this, but I am trying to automate it with KIF and learning on the fly. – jjj Oct 15 '14 at 00:50
  • Updated the answer. Is the bar button actually tappable? If KIF can't tap it, it sounds like it is still getting covered up by the tab bar item. Instead of inserting the button into the tab bar you should be inserting it into a view that overlays the tab bar. – Brian Nickel Oct 15 '14 at 16:52
  • Oh clear text is a brilliant idea! I don't think the button is actually tappable, it is indeed covered by the tab bar item. I was trying to get the tab bar item to be accessible without the title, but the clear text seems to solve the problem nicely. Again I didn't write this, I'm just trying to automate it and don't want to change too much code. Thanks for the help! – jjj Oct 15 '14 at 17:51
  • 1
    AccessibilityLabel doesn't seem to work in iOS 8 even when it's set. – Kamaros Mar 12 '15 at 20:44
  • 1
    This does not work for me on iOS 9 either. The UITabBarItem accepts an accessibility label but does not trigger VoiceOver speech when applied. Despite the accepted answer, a title value seems to be the only way to label the item with VoiceOver. Clear titleAttribute text color did not make titles disappear for me, so I resorted to the title offset hack described by OP, detailed here: http://mokagio.github.io/tech-journal/2015/02/17/ios-uitabbar-accessibility.html – seeker12 Oct 14 '15 at 23:25
5

If you are trying to set the accessibilityIdentifier on a UITabBarItem, it will not show up in the Accessibility Identifier unless you update the isAccessibilityElement property to true:

Example:

self.navigationController?.tabBarItem.isAccessibilityElement = true
self.navigationController?.tabBarItem.accessibilityIdentifier = "SomeIdName"
sorak
  • 2,607
  • 2
  • 16
  • 24
Lane Faison
  • 278
  • 4
  • 7