The subviews associated with the tab bar items in a UITabBar are of class UITabBarButton. By logging the subviews of a UITabBar with two tabs:
for (UIView* view in self.tabBar.subviews)
{
NSLog(view.description);
}
you get:
<_UITabBarBackgroundView: 0x6a91e00; frame = (0 0; 320 49); opaque = NO; autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x6a91e90>> - (null)
<UITabBarButton: 0x6a8d900; frame = (2 1; 156 48); opaque = NO; layer = <CALayer: 0x6a8db10>>
<UITabBarButton: 0x6a91b70; frame = (162 1; 156 48); opaque = NO; layer = <CALayer: 0x6a8db40>>
Based on this the solution is kind of trivial. The method I wrote for trying this out is as follows:
+ (CGRect)frameForTabInTabBar:(UITabBar*)tabBar withIndex:(NSUInteger)index
{
NSUInteger currentTabIndex = 0;
for (UIView* subView in tabBar.subviews)
{
if ([subView isKindOfClass:NSClassFromString(@"UITabBarButton")])
{
if (currentTabIndex == index)
return subView.frame;
else
currentTabIndex++;
}
}
NSAssert(NO, @"Index is out of bounds");
return CGRectNull;
}
It should be noted that the structure (subviews) of UITabBar and the class UITabBarButton itself are not part of the public API, so in theory it can change in any new iOS version without prior notification. Nevertheless it is unlikely that they would change such detail, and it works fine with iOS 5-6 and prior versions.