UITabBarItem 的宽度会有所不同,具体取决于有多少。
如何确定标签栏项目的宽度?
如果可能的话,我正在寻找一个属性,而不是数学公式,因为在 iPad 上,标签栏两侧也存在填充问题。考虑这些屏幕截图。注意 iPad 上标签栏项目两侧的填充(用红色框突出显示)。iPhone 上不存在此填充。
iPad:
iPhone:
UITabBarItem 的宽度会有所不同,具体取决于有多少。
如何确定标签栏项目的宽度?
如果可能的话,我正在寻找一个属性,而不是数学公式,因为在 iPad 上,标签栏两侧也存在填充问题。考虑这些屏幕截图。注意 iPad 上标签栏项目两侧的填充(用红色框突出显示)。iPhone 上不存在此填充。
iPad:
iPhone:
编辑:在下面的评论中已经注意到这个解决方案在 iOS 5 的 beta 版本中不起作用,所以准备修改它以满足您的需要。
我认为为了以正确的方式做到这一点,您必须能够到达每个标签栏项目的框架。幸运的是,这是可能的:
CGFloat tabBarTop = [[[self tabBarController] tabBar] frame].origin.y;
NSInteger index = [[self tabBarController] selectedIndex];
CGFloat tabMiddle = CGRectGetMidX([[[[[self tabBarController] tabBar] subviews] objectAtIndex:index] frame]);
上面的代码为您提供了标签栏顶部的 y 坐标和所选标签项中间的 x 坐标。从这里,你可以将你的指示器视图添加到标签栏控制器相对于这一点的视图中。
免责声明UITabBar
:这种方法的危险在于它通过访问其视图层次结构和frame
私有类实例的属性来窥探类的底层UITabBarButton
。这种方法有可能(但不太可能)会受到未来 iOS 更新的影响/破坏。但是,您没有访问任何私有 API,因此这不应该让您的应用被 App Store 拒绝。
我做了一个简单的 iPad 项目来演示它是如何工作的,并配有动画。
斯威夫特 3
我在 UIApplication 中创建了一个共享实例,然后拉了我的子视图宽度
tabBarController?.tabBar.subviews[1].frame.width
UITabBarItem 继承自 UIBarItem,UIBarItem 继承自 NSObject。由于它不是从 UIView 继承的,因此我不知道您是否能够仅通过属性获得所需的信息。我知道您不想要数学方法,但似乎获取标签栏的框架并除以标签的数量将是一个合理的选择,无论硬件如何(iphone vs ipad)都应该有效. 填充不应该影响这一点,对吧?所以你会有:
tabSize = tabbar.frame.size.width / [tabbar.items count];
tabBarStart = tabbar.frame.origin.x;
// Assume index of tabs starts at 0, then the tab in your pic would be tab 4
// targetX would be the center point of the target tab.
targetX = tabBarStart + (tabSize * targetTabIndex) + (tabSize / 2);
我也很想知道是否有人找到一个简单的属性来提供此信息。
我尝试了 UITabBar 的这两个属性:
@property(nonatomic) CGFloat itemWidth NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
@property(nonatomic) CGFloat itemSpacing NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
但正如 Vive 所说,获得零价值。所以我写了一些代码来获得正确的宽度:
CGFloat tabBarItemWidth = 0;
for (UIView *view in [self.tabBarController.tabBar subviews]) {
if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
if (tabBarItemWidth == 0) {
tabBarItemWidth = view.frame.origin.x;
} else {
tabBarItemWidth = view.frame.origin.x - tabBarItemWidth;
break;
}
}
}
为什么不使用第一个 UITabBarButton 的宽度?因为标签栏按钮之间有空格。:)
看了上面的答案:
UITabBar
工作项目不同。在 iPhone 中,它们填充整个宽度,在 iPad 中,它们水平居中。tabBar.itemWidth
您可以使用或设置宽度和间距的值tabBar.itemSpacing
。您无法从中读取系统间距或宽度 -0
除非您设置它,否则您将收到。所以这是我的示例如何获取所有帧UITabBarItems
:
// get all UITabBarButton views
NSMutableArray *tabViews = [NSMutableArray new];
for (UIView *view in self.tabBar.subviews) {
if ([view isKindOfClass:[UIControl class]]) {
[tabViews addObject:[NSValue valueWithCGRect:view.frame]];
}
}
// sort them from left to right
NSArray *sortedArray = [tabViews sortedArrayUsingComparator:^NSComparisonResult(NSValue *firstValue, NSValue *secondValue) {
CGRect firstRect = [firstValue CGRectValue];
CGRect secondRect = [secondValue CGRectValue];
return CGRectGetMinX(firstRect) > CGRectGetMinX(secondRect);
}];
现在你有一个框架表,对应于你的标签栏项目。你可以例如。在选定的索引按钮框架上放置一个 imageView。
CGRect frame = self.tabBar.bounds;
CGSize imageSize = CGSizeMake(CGRectGetWidth(frame) / self.tabBar.items.count, self.imageView.image.size.height);
CGRect selectedRect = sortedArray.count > self.selectedIndex ? [sortedArray[self.selectedIndex] CGRectValue] : CGRectZero;
[self.imageView setFrame:CGRectIntegral(CGRectMake(CGRectGetMinX(selectedRect), CGRectGetMaxY(frame) - imageSize.height,
CGRectGetWidth(selectedRect), imageSize.height))];
您可以使用私有属性获取 tabBarItem 视图view
。然后只是查看frame
。
- (CGRect)rectForTabBarItem:(UITabBarItem *)tabBarItem {
UIView *itemView = [tabBarItem valueForKey:@"view"];
return itemView.frame;
}
遍历 tabBar 的子视图并找到具有“UITabBarButton”类的视图。这些是每个选项卡项的视图。
for (UIView *view in self.tabBar.subviews) {
if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
// view.frame contains the frame for each item's view
// view.center contains the center of each item's view
}
}