[英]ios 11 UITabBar UITabBarItem positioning issue
我已经使用适用于 ios 11 的新 Xcode 9 beta 构建了我的应用程序。我发现 UITabBar 存在问题,其中项目通过 UITabBar 传播并且标题与图像右对齐。 我已尝试更改代码以使其正常工作,但仍未成功。
IOS 10+
IOS 11
我可以使用tabBarItem.titlePositionAdjustment
更改标题的位置,但这不是我的要求,因为它应该自动出现在图像本身的下方。 我尝试将tabbar.itemPositioning to UITabBarItemPositioningCentered
并尝试更改itemSpacing
和width
,但仍然无效。 有人可以帮我理解为什么会发生这种情况以及如何解决这个问题吗? 我希望它喜欢 ios 10+ 版本,并且图像是从 iPad 的最左角拍摄的。
我正在维护一个主要用 Objective-C 编写的大型 iPad 应用程序,该应用程序在多个 iOS 版本中幸存下来。 我遇到了需要 iOS 11 之前的选项卡栏外观(图标位于标题上方而不是旁边的图标)的情况,以用于几个选项卡栏。 我的解决方案是创建一个覆盖traitCollection
方法的 UITabBar 子类,以便它始终返回一个水平紧凑的特征集合。 这会导致 iOS 11 在所有标签栏按钮的图标下方显示标题。
为了使用它,将故事板中标签栏的自定义类设置为这个新的子类,并将代码中指向标签栏的任何出口更改为这种新类型(不要忘记导入头文件以下)。
在这种情况下,.h 文件几乎是空的:
//
// MyTabBar.h
//
#import <UIKit/UIKit.h>
@interface MyTabBar : UITabBar
@end
这是带有traitCollection
方法实现的 .m 文件:
//
// MyTabBar.m
//
#import "MyTabBar.h"
@implementation MyTabBar
// In iOS 11, UITabBarItem's 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
根据 John C 的回答,这里是 Swift 3 版本,无需 Storyboard 或子类化即可以编程方式使用:
extension UITabBar {
// Workaround for iOS 11's 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
}
}
为了避免弄乱任何其他特征,最好与超类结合:
- (UITraitCollection *)traitCollection
{
UITraitCollection *curr = [super traitCollection];
UITraitCollection *compact = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
return [UITraitCollection traitCollectionWithTraitsFromCollections:@[curr, compact]];
}
Swift 4 版本的子类避免了扩展/类别命名冲突:
class TabBar: UITabBar {
override var traitCollection: UITraitCollection {
guard UIDevice.current.userInterfaceIdiom == .pad else {
return super.traitCollection
}
return UITraitCollection(horizontalSizeClass: .compact)
}
}
如果你使用 Interface Builder 和 storyboards,你可以在UITabBarController
场景中选择标签栏视图,并在 Identity Inspector 中将其类更改为TabBar
:
注意:上面的这个修复似乎工作得很好。 不知道它将来会如何工作,但现在它工作得很好。
根据这个 WWDC talk ,这是新行为:
如果我没有正确阅读,则无法更改此行为:
我们为标签栏提供了这种全新的外观,无论是在横向还是在 iPad 上,我们都可以并排显示图标和文本。 尤其是在 iPhone 上,图标更小,标签栏更小,以提供更多垂直空间。
除了约翰的回答:
如果您有 4 个以上的标签栏项目并且不想要“更多”按钮,您必须采用不同的尺寸等级。 如果您想要项目的原始居中布局,您必须添加另一种方法,如下所示:
#import "PreIOS11TabBarController.h"
@interface PreIOS11TabBarController ()
@end
@implementation PreIOS11TabBarController
// In iOS 11, UITabBarItem's 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
@massimobio 的回答很好,但是它导致我的大导航栏标题消失了。 还没有进一步调查这个问题,但这似乎解决了它:
override var traitCollection: UITraitCollection {
guard UIDevice.current.userInterfaceIdiom == .pad else {
return super.traitCollection
}
return UITraitCollection(traitsFrom: [super.traitCollection, UITraitCollection(horizontalSizeClass: .compact)])
}
Max Desiatov 的回答部分有效。 它与亮/暗模式混为一谈。
这是另一个不干扰主要 traitCollection 的解决方案,但可以协同工作。
class CompactTabBar: UITabBar {
override var traitCollection: UITraitCollection {
guard UIDevice.current.userInterfaceIdiom == .pad else {
return super.traitCollection
}
let compactTrait = UITraitCollection(horizontalSizeClass: .compact)
let tabTrait = UITraitCollection(traitsFrom: [super.traitCollection, compactTrait])
return tabTrait
}
}
只需将此类从 UIStoryboard 中的 UITabBarController 分配给 UITabBar 对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.