【问题标题】:Remove tab bar item text, show only image删除标签栏项目文本,仅显示图像
【发布时间】:2014-12-17 02:47:51
【问题描述】:

简单的问题,如何删除标签栏项目文本并只显示图像?

我希望酒吧项目在 Instagram 应用中得到喜欢:

在 xcode 6 的检查器中,我删除了标题并选择了 @2x (50px) 和 @3x (75px) 图像。但是,图像不使用已删除文本的可用空间。任何想法如何实现与 instagram 应用程序中相同的标签栏项目图像?

【问题讨论】:

标签: ios swift uitabbaritem


【解决方案1】:

您应该使用UITabBarItemimageInsets 属性。这是示例代码:

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

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

【讨论】:

  • 您还可以在检查器中调整图像插入。
  • 幻数是个坏主意。请参阅我的答案,了解一种通用兼容的方式来完成同样的事情。
  • 这在 iOS 11 中不再有效 - 如果您双击活动选项卡,由于某种原因,它会加倍插入。
  • @BenGotow 同样的问题你有什么解决办法吗?
  • @DixitAkabari 其他人已经为 iOS 11 发布了一些不错的解决方案
【解决方案2】:

我在 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)
}

【讨论】:

  • 不用for var i = 0; i &lt; tabBar... ,你可以直接说; for tabBarItems in tabBar.items!
【解决方案3】:
// 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);
}

【讨论】:

  • 不删除标题,而是将文本颜色更改为清除。标题可能很有用。
  • 向爱德华多致敬!让我意识到一个不错的选择也是在项目的 titlePositionAjustement 上设置垂直 UIOffset
  • 你把它放在你的自定义 TabBar 控制器的什么地方?
【解决方案4】:

Swift 版本的 ddiego 答案

兼容 iOS 11

在设置viewController的标题后,在viewControllers的每个第一个孩子的viewDidLoad中调用这个函数

最佳实践:

如@daspianist 在 cmets 中建议的那样

创建一个类似此类 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)
        }
    }
}

【讨论】:

  • 很棒的功能!您也可以创建一个类似 class BaseTabBarController: UITabBarController, UITabBarControllerDelegate 的子类,并将此函数放入子类的 viewDidLoad
【解决方案5】:

如果您使用情节提要,这将是您的最佳选择。它循环遍历所有选项卡栏项目,并且对于每个项目,它都将标题设置为空,并使图像全屏显示。 (您必须在情节提要中添加了图像)

for tabBarItem in tabBar.items!
{
   tabBarItem.title = ""
   tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
}

【讨论】:

  • 请注意,如果您不设置顶部和底部插图,图像最终会变形。
【解决方案6】:

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

【讨论】:

  • 这似乎是一种更清洁的方法。 +1 @Oleg 这应该被标记为答案。
【解决方案7】:

除了最佳答案之外,这是一种更好、更简单的方法:

[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]}
                                         forState:UIControlStateNormal];
[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]}
                                         forState:UIControlStateHighlighted];

把它放在你的AppDelegate.didFinishLaunchingWithOptions 中,这样它就会影响你应用程序整个生命周期中的所有标签栏按钮。

【讨论】:

  • 这只是隐藏标题,不调整图片位置。
  • 是的,但问题没有提到调整图像。只是隐藏文字。并且隐藏文本而不利于从视图控制器中删除标题似乎是错误的。尤其是当您可以使用该标题将其显示为您的导航视图控制器的一部分时
【解决方案8】:

这是您在情节提要中执行此操作的方法。

清除标题文字,像下面截图一样设置图片插入

记住图标大小应遵循apple design guideline

这意味着@1x 应该有 25px x 25px,@2x 应该有 50px x 50px,@3x 应该有 75px x 75px

【讨论】:

    【解决方案9】:

    Swift 中最小的、安全的 UITabBarController 扩展(基于@korgx9 的回答):

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

    【讨论】:

      【解决方案10】:

      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 子类的“覆盖 func viewDidLayoutSubviews”中。我将 tabBarController 子类化并将其命名为
      • 解决方案对我很有效。我用它作为扩展,所以添加起来更简单
      • @LanceSamaria 这工作不需要我触摸标签栏控制器代码
      【解决方案11】:

      Swift 4 方法

      我能够通过实现一个接受 TabBarItem 并对其进行一些格式化的函数来达到目的。

      将图像稍微向下移动以使其更加居中,同时隐藏标签栏的文本。 比仅将其标题设置为空字符串效果更好,因为当您也有一个 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()
      

      【讨论】:

        【解决方案12】:

        代码:

        private func removeText() {
            if let items = yourTabBarVC?.tabBar.items {
               for item in items {
                  item.title = ""
               }
            }
         }
        

        【讨论】:

          【解决方案13】:

          基于answer of ddiego,在Swift 4.2中:

          extension UITabBarController {
              func cleanTitles() {
                  guard let items = self.tabBar.items else {
                      return
                  }
                  for item in items {
                      item.title = ""
                      item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
                  }
              }
          }
          

          你只需要在你的视图控制器中调用self.tabBarController?.cleanTitles()

          【讨论】:

            【解决方案14】:

            最简单的方法并且始终有效:

            class TabBar: UITabBar {
            
                override func layoutSubviews() {
                    super.layoutSubviews()
            
                    subviews.forEach { subview in
                        if subview is UIControl {
                            subview.subviews.forEach {
                                if $0 is UILabel {
                                    $0.isHidden = true
                                    subview.frame.origin.y = $0.frame.height / 2.0
                                }
                            }
                        }
                    }
                }
            }
            

            【讨论】:

              【解决方案15】:

              基于此页面上的所有出色答案,我设计了另一个解决方案,该解决方案还允许您再次显示标题。我没有删除标题的内容,而是将字体颜色更改为透明。

              extension UITabBarItem {
              
                  func setTitleColorFor(normalState: UIColor, selectedState: UIColor) {
                      self.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: normalState], for: .normal)
                      self.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: selectedState], for: .selected)
                  }
              
              }
              
              
              extension UITabBarController {
              
                  func hideItemsTitle() {
              
                      guard let items = self.tabBar.items else {
                          return
                      }
              
                      for item in items {
                          item.setTitleColorFor(normalState: UIColor(white: 0, alpha: 0), selectedState: UIColor(white: 0, alpha: 0))
                          item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
                      }
              
                  }
              
                  func showItemsTitle() {
              
                      guard let items = self.tabBar.items else {
                          return
                      }
              
                      for item in items {
                          item.setTitleColorFor(normalState: .black, selectedState: .yellow)
                          item.imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
                      }
              
                  }
              
              }
              

              【讨论】:

                【解决方案16】:

                在我的例子中,TabBar 和其他导航流程中使用了相同的 ViewController。在我的 ViewController 中,我设置了出现在 TabBar 中的 self.title = "Some Title",无论是否设置标题 nil 或在标签栏中添加它时为空白。我还设置了imageInsets 如下:

                item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)

                所以在我的 ViewController 中,我处理了如下导航标题:

                if isFromTabBar {
                   // Title for NavigationBar when ViewController is added in TabBar
                   // NOTE: Do not set self.title = "Some Title" here as it will set title of tabBarItem
                   self.navigationItem.title = "Some Title"
                } else {
                   // Title for NavigationBar when ViewController is opened from navigation flow
                   self.title = "Some Title"
                }
                

                【讨论】:

                  【解决方案17】:

                  创建一个 UITabBarController 的子类并将其分配给您的 tabBar ,然后在 viewDidLoad 方法中放置这行代码:

                  tabBar.items?.forEach({ (item) in
                          item.imageInsets = UIEdgeInsets.init(top: 8, left: 0, bottom: -8, right: 0)
                      })
                  

                  【讨论】:

                    【解决方案18】:

                    自定义标签栏 - iOS 13、Swift 5、XCode 11

                    • 没有文字的 TabBar 项
                    • TabBar 项目垂直居中
                    • 圆角 TabBar 视图
                    • TabBar 动态位置和框架

                    基于故事板。它也可以通过编程轻松实现。只需 4 个步骤:

                    1. 标签栏图标必须有 3 种尺寸,黑色。通常,我从 fa2png.io 下载 - 尺寸:25x25、50x50、75x75。 PDF 图像文件不起作用!

                    2. 在 Storyboard 中为标签栏项目设置您要通过属性检查器使用的图标。 (见截图)

                    1. 自定义 TabBarController -> 新文件 -> 类型:UITabBarController -> 在情节提要上设置。 (见截图)

                    1. UITabBarController 类

                      类 RoundedTabBarViewController: UITabBarController {

                      override func viewDidLoad() {
                          super.viewDidLoad()
                      
                          // Do any additional setup after loading the view.
                          // Custom tab bar view
                          customizeTabBarView()
                      }
                      
                      private func customizeTabBarView() {
                          let tabBarHeight = tabBar.frame.size.height
                          self.tabBar.layer.masksToBounds = true
                          self.tabBar.isTranslucent = true
                          self.tabBar.barStyle = .default
                          self.tabBar.layer.cornerRadius = tabBarHeight/2
                          self.tabBar.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]
                      }
                      
                      override func viewDidLayoutSubviews() {
                          super.viewDidLayoutSubviews()
                          let viewWidth = self.view.bounds.width
                          let leadingTrailingSpace = viewWidth * 0.05
                      
                          tabBar.frame = CGRect(x: leadingTrailingSpace, y: 200, width: viewWidth - (2 * leadingTrailingSpace), height: 49)
                      }
                      

                      }

                    2. 结果

                    【讨论】:

                      【解决方案19】:

                      如果您希望在不使用幻数的情况下使标签居中/更改图像插图,以下对我有用(在 Swift 5.2.2 中):

                      UITabBarController 子类中,您可以在设置视图控制器后添加添加图片插图。

                      override var viewControllers: [UIViewController]? {
                          didSet {
                            addImageInsets()
                          }
                      }
                      
                      func addImageInsets() {
                          let tabBarHeight = tabBar.frame.height
                      
                          for item in tabBar.items ?? [] where item.image != nil {
                            let imageHeight = item.image?.size.height ?? 0
                            let inset = CGFloat(Int((tabBarHeight - imageHeight) / 4))
                            item.imageInsets = UIEdgeInsets(top: inset,
                                                            left: 0,
                                                            bottom: -inset,
                                                            right: 0)
                          }
                      }
                      

                      上面的几个选项列出了处理隐藏文本的解决方案。

                      【讨论】:

                        猜你喜欢
                        • 2014-10-10
                        • 1970-01-01
                        • 2017-02-27
                        • 2018-02-11
                        • 2013-07-29
                        • 1970-01-01
                        • 1970-01-01
                        • 2020-08-01
                        • 2015-06-26
                        相关资源
                        最近更新 更多