ios 11 UITabBar UITabBarItem定位问题

Gih*_*han 48 objective-c uitabbaritem uitabbar ios ios11

我已经使用ios 11的新Xcode 9 beta构建了我的应用程序.我发现UITabBar存在问题,其中项目通过UITabBar传播,标题与图像右对齐.我已经尝试更改代码以使其工作但仍然不成功.

ios 10+

在此输入图像描述

ios 11

在此输入图像描述

我可以改变标题的位置tabBarItem.titlePositionAdjustment 但是这不是我的要求,因为它应该自动地低于图像本身.我试着设置tabbar.itemPositioning to UITabBarItemPositioningCentered,也试图改变itemSpacingwidth,但仍然没有工作.有人可以帮助我理解为什么会这样,以及如何解决这个问题?我希望它喜欢ios 10+版本,图像是从iPad的最左边角落拍摄的.

小智 41

我正在维护一个大型的iPad应用程序,该应用程序主要使用Objective-C编写,并且在几个iOS版本中幸 对于一些标签栏,我遇到了需要iOS 11前标签栏外观(标题上方的图标而不是旁边的图标)的情况.我的解决方案是创建一个UITabBar的子类来覆盖该traitCollection方法,以便它总是返回一个水平紧凑的特征集合.这会导致iOS 11在所有标签栏按钮的图标下方显示标题.

为了使用它,将storyboard中标签栏的自定义类设置为这个新子类,并将代码中指向标签栏的任何出口更改为此新类型(不要忘记导入头文件)下面).

在这种情况下,.h文件几乎是空的:

//
//  MyTabBar.h
//

#import <UIKit/UIKit.h>

@interface MyTabBar : UITabBar

@end
Run Code Online (Sandbox Code Playgroud)

这是带有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
Run Code Online (Sandbox Code Playgroud)

  • 我不使用情节提要/ IB,但是通过将UITabBarController而不是UITabBar子类化并重写相同的traitCollection方法,我可以获得完全相同的效果。 (2认同)
  • 实际上划伤了.不建议对UITabBarController进行子类化,实际上导航栏在执行此操作时会破坏iOS 11 GM. (2认同)
  • 不幸的是,这会打破导航栏外观(UIBarButtonItems和导航栏标题):https://forums.developer.apple.com/thread/86013 (2认同)
  • @NikoZarzani只有在您继承UITabBarController时,它才会破坏导航栏的外观.如果您将UITabBar子类化为导航栏外观,则保持原样. (2认同)
  • 可悲的是,在iOS 13中,这开始产生此警告`Class MyClass会覆盖-traitCollection getter,这不受支持。如果您尝试覆盖特征,则必须使用适当的API。 (2认同)

mas*_*bio 36

根据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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不建议这样做,虽然听到它现在有效但我并不感到惊讶.如果`UITabBar`也覆盖`traitCollection`,和/或如果在某个地方实现它的`UITabBar`上有另一个扩展(或Objective-C类),则结果是未定义的.你最好离子类化(这很烦人).有关详细信息,请参阅/sf/ask/368692411/. (2认同)
  • 导致 iOS 17 崩溃,使用 @Balázs Vincze 的答案 (2认同)

小智 20

为了避免搞乱任何其他特征,与超类结合起来并不是更好:

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

  return [UITraitCollection traitCollectionWithTraitsFromCollections:@[curr, compact]];
}
Run Code Online (Sandbox Code Playgroud)

  • iOS 13在控制台中吐出了大量有关此解决方案已修复的特征的调试。尽管“ [[TraitCollection]类CustomiPadUITabBar类覆盖-traitCollection getter,但不支持,但仍在报告”。如果要覆盖特征,则必须使用适当的API。” 任何想法如何摆脱那个?是否有“适当的API”? (4认同)

Dan*_*ark 15

注意: 上面的这个修复似乎工作得很好.不确定它将来会如何运作,但现在它的运作情况非常好.


根据WWDC的讲话,这是以下新行为:

  • iPhone在风景中
  • iPad一直都是

如果我正确阅读,则无法更改此行为:

我们为标签栏提供了全新的外观,包括横向和iPad,我们并排显示图标和文字.特别是在iPhone上,图标较小,标签栏较小,垂直空间更大.


Max*_*tov 11

带有子类的Swift 4版本可以避免扩展/类别命名冲突:

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

    return UITraitCollection(horizontalSizeClass: .compact)
  }
}
Run Code Online (Sandbox Code Playgroud)

如果使用Interface Builder和故事板,则可以在UITabBarController场景中选择选项卡栏视图,并TabBar在Identity Inspector中将其类更改为:

在此输入图像描述

  • 导致 iOS 17 崩溃,使用 @Balázs Vincze 的答案 (2认同)