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.
Ответы
Ответ 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