移除选项卡条目文本,仅显示图像

92

简单问题,如何去除选项卡条目的文本并仅显示图像?

我希望选项卡项与Instagram应用程序中的类似:

输入图像描述

在Xcode 6的检查器中,我删除了标题并选择了@2x(50px)和@3x(75px)的图像。但是,该图像没有使用已删除文本的自由空间。有什么想法可以实现与Instagram应用程序中相同的选项卡条目图像?


3
抱歉,我只能用英文回答你的问题。 - algal
1
使用 "" 作为标题,也许? - holex
1
设置偏移量只是一个技巧,正确的答案略低一些。您应该使用navigationItem.title =“某个标题”。 - Davit Siradeghyan
19个回答

134

你应该使用 UITabBarItemimageInsets 属性进行操作。以下是样例代码:

let tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "more")
tabBarItem.imageInsets = UIEdgeInsets(top: 9, left: 0, bottom: -9, right: 0)

UIEdgeInsets中的数值取决于您的图像大小。这是我的应用程序中该代码的结果:

输入图像描述


25
您还可以在检查器中调整图像的插图。 - DarkLeafyGreen
魔数是一个不好的想法。请查看我的答案,以找到一种普遍兼容的方法来完成相同的事情。 - Ezekiel Victor
4
在iOS 11中,这个操作不再奏效——如果你双击活动选项卡,它会因某种原因使内部嵌入加倍。 - Ben Gotow
@BenGotow 你遇到了同样的问题,有解决方案吗? - Dixit Akabari
@DixitAkabari其他人已经发布了一些适用于iOS 11的好解决方案。 - Pranav Kasetti
Ezekial Victor的回答忽略了有关图像插入的问题。你将不得不使用“魔术数字”。 - gma

79
// Remove the titles and adjust the inset to account for missing title
for(UITabBarItem * tabBarItem in self.tabBar.items){
    tabBarItem.title = @"";
    tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0);
}

1
不要删除标题,而是将文本颜色更改为透明。标题可能很有用。 - Eduardo Mauro
1
向Eduardo致敬!让我意识到一个好的选择是在项目的titlePositionAjustement上设置垂直UIOffset。 - Julius
2
你把这个放在自定义 TabBar 控制器的哪里? - UKDataGeek

70

以下是在故事板中的操作步骤。

清除标题文本,并设置图像插图,如下方屏幕截图所示:

输入图像描述

请记住,图标大小应遵循Apple设计准则

输入图像描述

这意味着您应该拥有@1x尺寸为25px x 25px,@2x尺寸为50px x 50px,@3x尺寸为75px x 75px的图标。


52

使用将每个UITabBarItemtitle属性设置为""并更新imageInsets的方法,在视图控制器self.title被设置时将无法正常工作。例如,如果UITabBarControllerself.viewControllers嵌入了UINavigationController中,并且您需要在导航栏上显示标题。在这种情况下,请直接使用self.navigationItem.title而不是self.title来设置UINavigationItem的标题。


3
这个方法看起来更加简洁。+1 @Oleg 这应该标记为答案。 - akseli

27
如果您使用的是故事板,则这将是您最佳的选择。它循环遍历所有选项卡栏项目,并为每个项目设置标题为空,并将图像设置为全屏。(您必须在故事板中添加图像)
for tabBarItem in tabBar.items!
{
   tabBarItem.title = ""
   tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
}

需要注意的是,如果您不设置顶部和底部插图,则图片最终会变形。 - Julius

26

ddiego的Swift版本答案

iOS 11兼容

在设置viewController标题后,在每个视图控制器的第一个子项的viewDidLoad中调用此函数。

最佳实践:

如@daspianist在评论中建议的那样,创建一个类似于BaseTabBarController的子类:UITabBarController,UITabBarControllerDelegate,并将此函数放入子类的viewDidLoad中。

func removeTabbarItemsText() {

    var offset: CGFloat = 6.0

    if #available(iOS 11.0, *), traitCollection.horizontalSizeClass == .regular {
        offset = 0.0
    }

    if let items = tabBar.items {
        for item in items {
            item.title = ""
            item.imageInsets = UIEdgeInsets(top: offset, left: 0, bottom: -offset, right: 0)
        }
    }
}

2
很棒的函数!你也可以像这样创建一个子类 class BaseTabBarController: UITabBarController, UITabBarControllerDelegate,并将此函数放在子类的 viewDidLoad 中。 - daspianist

16

iOS 11对许多解决方案产生了影响,因此我通过子类化UITabBar并覆盖layoutSubviews来解决了iOS 11上的问题。

class MainTabBar: UITabBar {

    override func layoutSubviews() {
        super.layoutSubviews()

        // iOS 11: puts the titles to the right of image for horizontal size class regular. Only want offset when compact.
        // iOS 9 & 10: always puts titles under the image. Always want offset.
        var verticalOffset: CGFloat = 6.0

        if #available(iOS 11.0, *), traitCollection.horizontalSizeClass == .regular {
            verticalOffset = 0.0
        }

        let imageInset = UIEdgeInsets(
            top: verticalOffset,
            left: 0.0,
            bottom: -verticalOffset,
            right: 0.0
        )

        for tabBarItem in items ?? [] {
            tabBarItem.title = ""
            tabBarItem.imageInsets = imageInset
        }
    }
}

这是唯一对我有效的方法,但我不得不将代码放在MyTabBarController子类的“override func viewDidLayoutSubviews”中。我创建了一个名为的子类tabBarController。 - Lance Samaria
解决方案对我很有效,非常好用。我将其作为扩展使用,这样添加就更简单了。 - Michal Gumny
@LanceSamaria 这个方法可行,而且我不需要修改选项卡控制器的代码。 - Pranav Kasetti

12

我在我的BaseTabBarController的viewDidLoad中使用了以下代码。请注意,在我的示例中,我有5个选项卡,并且所选图像将始终为base_image +“_selected”。

// Get tab bar and set base styles
let tabBar = self.tabBar;
tabBar.backgroundColor = UIColor.whiteColor()

// Without this, images can extend off top of tab bar
tabBar.clipsToBounds = true

// For each tab item..
let tabBarItems = tabBar.items?.count ?? 0
for i in 0 ..< tabBarItems {
    let tabBarItem = tabBar.items?[i] as UITabBarItem

    // Adjust tab images (Like mstysf says, these values will vary)
    tabBarItem.imageInsets = UIEdgeInsetsMake(5, 0, -6, 0);

    // Let's find and set the icon's default and selected states
    // (use your own image names here)
    var imageName = ""
    switch (i) {
    case 0: imageName = "tab_item_feature_1"
    case 1: imageName = "tab_item_feature_2"
    case 2: imageName = "tab_item_feature_3"
    case 3: imageName = "tab_item_feature_4"
    case 4: imageName = "tab_item_feature_5"
    default: break
    }
    tabBarItem.image = UIImage(named:imageName)!.imageWithRenderingMode(.AlwaysOriginal)
    tabBarItem.selectedImage = UIImage(named:imageName + "_selected")!.imageWithRenderingMode(.AlwaysOriginal)
}

1
你可以使用 for tabBarItems in tabBar.items! 代替 for var i = 0; i < tabBar... - Jesse Onolemen

10

Swift 4做法

我通过实现一个函数来完成技巧,该函数接收TabBarItem并对其进行一些格式化。

将图像下移一点以使其更加居中,并隐藏Tab Bar的文本。这比仅将其标题设置为空字符串要好,因为当您还有NavigationBar时,TabBar在选择时会恢复viewController的标题。

func formatTabBarItem(tabBarItem: UITabBarItem){
    tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
    tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:UIColor.clear], for: .selected)
    tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:UIColor.clear], for: .normal)
}

最新的语法

extension UITabBarItem {
    func setImageOnly(){
        imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
        setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.clear], for: .selected)
        setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.clear], for: .normal)
    }
 }

只需在您的 tabBar 中使用它:

tabBarItem.setImageOnly()

6

一份基于@korgx9答案的Swift编写的最小安全UITabBarController扩展:

extension UITabBarController {
  func removeTabbarItemsText() {
    tabBar.items?.forEach {
      $0.title = ""
      $0.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接