繁体   English   中英

ios 11 UITabBar UITabBarItem 定位问题

[英]ios 11 UITabBar UITabBarItem positioning issue

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

IOS 10+

在此处输入图像描述

IOS 11

在此处输入图像描述

我可以使用tabBarItem.titlePositionAdjustment更改标题的位置,但这不是我的要求,因为它应该自动出现在图像本身的下方。 我尝试将tabbar.itemPositioning to UITabBarItemPositioningCentered并尝试更改itemSpacingwidth ,但仍然无效。 有人可以帮我理解为什么会发生这种情况以及如何解决这个问题吗? 我希望它喜欢 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 ,这是新行为:

  • iPhone 横屏
  • 无时无刻不在 iPad

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

我们为标签栏提供了这种全新的外观,无论是在横向还是在 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM