简体   繁体   English

如何获得UITabBarItem的宽度?

[英]How do I get the width of a UITabBarItem?

The width of a UITabBarItem varies, depending on how many there are. UITabBarItem的宽度会有所不同,具体取决于有多少。

How do I determine how wide my tab bar items are? 如何确定标签栏项目的宽度?

I'm looking for a property if possible, as opposed to a mathematical formula, since on the iPad, there is also an issue of padding on either side of the tab bar. 如果可能的话,我正在寻找一个属性,而不是数学公式,因为在iPad上,标签栏的两侧也存在填充问题。 Consider these screenshots. 考虑这些截图。 Notice the padding on either side of the tab bar items on the iPad (highlighted with the red boxes). 注意iPad上标签栏项目两侧的填充(用红色框突出显示)。 This padding does not exist on the iPhone. iPhone上不存在此填充。

The iPad: iPad:

在此输入图像描述

The iPhone: iPhone: 在此输入图像描述

Edit : It has been noted in the comments below that this solution did not work in a beta version of iOS 5, so be prepared to modify it to meet your needs. 编辑 :在下面的评论中已经注意到此解决方案在iOS 5的测试版中不起作用,因此请准备好修改它以满足您的需求。

I think in order to do this the right way, you have to be able to get to the frame of each tab bar item. 我认为为了以正确的方式做到这一点,你必须能够到达每个标签栏项目的框架。 Fortunately, this is possible: 幸运的是,这是可能的:

CGFloat tabBarTop = [[[self tabBarController] tabBar] frame].origin.y;
NSInteger index = [[self tabBarController] selectedIndex];
CGFloat tabMiddle = CGRectGetMidX([[[[[self tabBarController] tabBar] subviews] objectAtIndex:index] frame]);

The above code gives you the y coordinate of the top of the tab bar and the x coordinate of the middle of the selected tab item. 上面的代码为您提供了选项卡栏顶部的y坐标和所选选项卡项中间的x坐标。 From here, you can add your indicator view to the tab bar controller's view relative to this point. 从这里,您可以将指标视图添加到相对于此点的选项卡栏控制器视图中。

Disclaimer : The danger with this approach is that it peeks under the hood of the UITabBar class by accessing its view hierarchy and the frame property of instances of the private UITabBarButton class. 免责声明 :这种方法的危险在于它通过访问其视图层次结构和私有UITabBarButton类的实例的frame属性来窥视UITabBar类的UITabBarButton It is possible (however unlikely) that this approach could be affected/broken by a future iOS update. 未来的iOS更新可能会(但不太可能)影响/破坏此方法。 However, you're not accessing any private APIs, so this shouldn't get your app rejected from the App Store. 但是,您没有访问任何私有API,因此不应该从App Store中拒绝您的应用程序。

I made a simple iPad project demonstrating how it works , complete with animations. 我制作了一个简单的iPad项目,展示了它的工作原理 ,并完成了动画制作。

Swift 3 斯威夫特3

I created a shared instance in UIApplication then pulled my subviews width 我在UIApplication中创建了一个共享实例,然后拉出了我的子视图宽度

tabBarController?.tabBar.subviews[1].frame.width

I tried these 2 properties of UITabBar: 我尝试了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;

But get zero value as Vive said. 但Vive说,获得零价值。 So I wrote some codes to get the right width: 所以我写了一些代码来获得正确的宽度:

    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;
            }
        }
    }

Why not use the width of first UITabBarButton? 为什么不使用第一个UITabBarButton的宽度? Because there are spaces between tab bar buttons. 因为标签栏按钮之间有空格。 :) :)

Looking at the answer above: 看看上面的答案:

  1. Items in the UITabBar work different in the iPhone and the iPad. UITabBar项目在iPhone和iPad中的工作方式不同。 In the iPhone they fill whole width, in the iPad they're centered horizontally. 在iPhone中,它们填充整个宽度,在iPad中它们是水平居中的。
  2. There is a spacing between the items in the iPad. iPad中的物品之间有间距。
  3. You can set the values for both width and spacing using tabBar.itemWidth or tabBar.itemSpacing . 您可以使用tabBar.itemWidthtabBar.itemSpacing设置宽度和间距的值。 You are not able to read system spacing or width from it - you'll receive 0 unless you set it. 您无法从中读取系统间距或宽度 - 除非您设置它,否则您将收到0

So here's my sample how to get frames of all UITabBarItems : 所以这是我的示例如何获取所有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);
    }];

Now you have a table of frames, corresponding to your tabbar items. 现在您有一个框架表,对应于您的tabbar项目。 You can eg. 你可以,例如。 place an imageView on selected index button frame. 在所选索引按钮框架上放置一个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))];

You can get tabBarItem view using private property view . 您可以使用私有属性view获取tabBarItem view Then just get view frame . 然后只是获取视图frame

- (CGRect)rectForTabBarItem:(UITabBarItem *)tabBarItem {
    UIView *itemView = [tabBarItem valueForKey:@"view"];
    return itemView.frame;
} 

UITabBarItem inherits from UIBarItem, which inherits from NSObject. UITabBarItem继承自UIBarItem,它继承自NSObject。 Since it doesn't inherit from UIView, I don't know that you're going to be able to get the information you want just with a property. 由于它不是从UIView继承,我不知道你将能够获得你想要的信息只是一个属性。 I know you don't want a mathematical way of doing it, but it would seem that getting the frame of the tab bar and dividing by the # of tabs would be a reasonable option that should work regardless of the hardware (iphone vs ipad). 我知道你不需要一种数学方法来做这件事,但似乎获得标签栏的框架并除以标签数量将是一个合理的选择,无论硬件如何都应该有效(iphone vs ipad) 。 Padding shouldn't affect this, right? 填充不应该影响这个,对吧? So you'd have: 所以你有:

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);

I, as well, am interested to know if someone finds a simple property to give this information. 我也有兴趣知道是否有人找到了一个简单的属性来提供这些信息。

Loop through your tabBar's subviews and find the views with the class "UITabBarButton". 循环浏览tabBar的子视图,并使用“UITabBarButton”类查找视图。 These are the views for each tab item. 这些是每个标签项的视图。

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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM