Подтвердить что ты не робот

Ios 11 UITabBar UITabBarItem проблема позиционирования

Я создал свое приложение, используя новую версию Xcode 9 для ios 11. Я нашел проблему с UITabBar, где элементы распространяются через UITabBar, а заголовок правильно выровнен по изображению. Я попытался изменить код, чтобы заставить его работать, но все еще не удалось.

ios 10+

введите описание изображения здесь

ios 11

введите описание изображения здесь

Я могу изменить положение заголовка, используя tabBarItem.titlePositionAdjustment Но это не мое требование, так как оно должно автоматически выходить за рамки самого изображения. Я попытался установить tabbar.itemPositioning to UITabBarItemPositioningCentered, а также попытался изменить itemSpacing и width, но все равно не работал. Может кто-нибудь помочь мне понять, почему это происходит и как это исправить? Я хочу, чтобы она понравилась версия ios 10+, а изображения взяты из левого угла iPad.

4b9b3361

Ответ 1

Я поддерживаю большое приложение для iPad, написанное в основном в Objective-C, которое пережило несколько выпусков iOS. Я столкнулся с ситуацией, когда мне понадобился внешний вид панели перед iOS 11 (со значками над названиями, а не рядом с ними) для нескольких полос вкладок. Мое решение состояло в создании подкласса UITabBar, который переопределяет метод traitCollection, чтобы он всегда возвращал горизонтально-компактную коллекцию признаков. Это заставляет iOS 11 отображать заголовки под значками для всех кнопок панели вкладок.

Чтобы использовать это, установите пользовательский класс полос вкладок в раскадровке для этого нового подкласса и измените любые выходы в коде, которые указывают на панели вкладок этого нового типа (не забудьте импортировать файл заголовка ниже).

В этом случае файл .h довольно пуст:

//
//  MyTabBar.h
//

#import <UIKit/UIKit.h>

@interface MyTabBar : UITabBar

@end

Вот файл .m с реализацией метода traitCollection:

//
//  MyTabBar.m
//

#import "MyTabBar.h"

@implementation MyTabBar

// In iOS 11, UITabBarItem have the title to the right of the icon in horizontally regular environments
// (i.e. the iPad).  In order to keep the title below the icon, it was necessary to subclass UITabBar and override
// traitCollection to make it horizontally compact.

- (UITraitCollection *)traitCollection {
    return [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
}

@end

Ответ 2

Основываясь на ответе Джона С, вот версия Swift 3, которая может быть использована программно без необходимости в раскадровке или подклассе:

extension UITabBar {
    // Workaround for iOS 11 new UITabBar behavior where on iPad, the UITabBar inside
    // the Master view controller shows the UITabBarItem icon next to the text
    override open var traitCollection: UITraitCollection {
        if UIDevice.current.userInterfaceIdiom == .pad {
            return UITraitCollection(horizontalSizeClass: .compact)
        }
        return super.traitCollection
    }
}

Ответ 3

Чтобы избежать испортить любые другие черты, лучше не сочетаться с суперклассами:

- (UITraitCollection *)traitCollection
{
  UITraitCollection *curr = [super traitCollection];
  UITraitCollection *compact = [UITraitCollection  traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];

  return [UITraitCollection traitCollectionWithTraitsFromCollections:@[curr, compact]];
}

Ответ 4

ПРИМЕЧАНИЕ. Это исправление, показанное выше, работает довольно хорошо. Не уверен, как это будет работать в будущем, но сейчас это работает довольно хорошо.


Согласно этому докладу WWDC, это новое поведение для:

  • iPhone в ландшафте
  • iPad все время

И если я правильно читаю, это поведение нельзя изменить:

У нас есть совершенно новый внешний вид для панели вкладок, как в альбомной ориентации, так и на iPad, где мы показываем значок и текст рядом. И, в частности, на iPhone значок меньше, а панель вкладок меньше, чтобы оставить немного больше места по вертикали.

Ответ 5

Версия Swift 4 с подклассом, который позволяет избежать коллизии имен расширения/категории:

class TabBar: UITabBar {
  override var traitCollection: UITraitCollection {
    guard UIDevice.current.userInterfaceIdiom == .pad else {
      return super.traitCollection
    }

    return UITraitCollection(horizontalSizeClass: .compact)
  }
}

Если вы используете Interface Builder и раскадровки, вы можете выбрать представление панели вкладок в сцене UITabBarController и изменить его класс на TabBar в Identity Inspector:

enter image description here

Ответ 6

В дополнение к Джону ответьте:

Если у вас есть более 4 элементов панели табуляции, и вы не хотите кнопку "Больше", вы должны взять другой класс размеров. И если вы хотите исходную центральную компоновку элементов, вам нужно добавить еще один способ:

#import "PreIOS11TabBarController.h"

@interface PreIOS11TabBarController ()

@end

@implementation PreIOS11TabBarController

// In iOS 11, UITabBarItem have the title to the right of the icon in horizontally regular environments
// (i.e. the iPad).  In order to keep the title below the icon, it was necessary to subclass UITabBar and override
// traitCollection to make it horizontally compact.

- (UITraitCollection *)traitCollection {
    return [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
}


- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    self.tabBar.itemPositioning = UITabBarItemPositioningCentered;
}

@end