Как получить ширину UITabBarItem?

Ширина UITabBarItem варьируется в зависимости от того, сколько из них существует.

Как определить, насколько широки мои элементы панели вкладок?

Я ищу свойство, если это возможно, в отличие от математической формулы, поскольку на iPad есть проблема с заполнением по обе стороны панели вкладок. Рассмотрим эти скриншоты. Обратите внимание на заполнение с обеих сторон элементов панели вкладок на iPad (выделено красными ячейками). Это дополнение не существует на iPhone.

iPad:

enter image description here

iPhone: enter image description here

Ответы

Ответ 1

Изменить. В комментариях ниже было отмечено, что это решение не работает в бета-версии iOS 5, поэтому будьте готовы изменить его в соответствии с вашими потребностями.

Я думаю, для того, чтобы сделать это правильно, вы должны иметь возможность добраться до кадра каждого элемента панели табуляции. К счастью, это возможно:

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, демонстрирующий, как он работает, в комплекте с анимацией.

Ответ 2

UITabBarItem наследует от 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);

Мне также интересно узнать, найдет ли кто-то простое свойство для предоставления этой информации.

Ответ 3

Я пробовал эти 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;

Но получим нулевое значение, как сказал Вив. Поэтому я написал несколько кодов, чтобы получить правильную ширину:

    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? Потому что есть пробелы между кнопками панели вкладок.:)

Ответ 4

Глядя на ответ выше:

  • Элементы в UITabBar работают разные в iPhone и iPad. В iPhone они заполняют всю ширину, в iPad они расположены по горизонтали.
  • Между элементами в 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);
    }];

Теперь у вас есть таблица кадров, соответствующая вашим вкладкам. Вы можете, например. поместите изображение на выбранную рамку кнопки индекса.

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

Ответ 5

Вы можете получить представление tabBarItem с помощью частной собственности view. Затем просто получите представление frame.

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

Ответ 6

Swift 3

Я создал общий экземпляр в UIApplication, затем потянул ширину моего поднабора

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

Ответ 7

Прокрутите свои подзоны tabBar и найдите представления с классом "UITabBarButton". Это виды для каждого элемента табуляции.

for (UIView *view in self.tabBar.subviews) {
    if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
        // view.frame contains the frame for each item view
        // view.center contains the center of each item view
    }
}