【问题标题】:How to add small red dot in UITabBarItem如何在 UITabBarItem 中添加小红点
【发布时间】:2015-09-29 00:40:03
【问题描述】:

如何在UITabBarItem 的右上角添加红点。

我已经搜索了一段时间,有些人说这可以设置UITabBarItem的徽章值。但是当我尝试将徽章值设置为空白空间“”时,红点有点大。如何我能买到合适的吗?非常感谢。

【问题讨论】:

标签: ios swift uitabbaritem badge


【解决方案1】:

为您想要的UITabBarItem 设置badgeValue,如下所示:

    // for first tab
    (tabBarController!.tabBar.items!.first! as! UITabBarItem).badgeValue = "1"

    //for second tab
    (tabBarController!.tabBar.items![1] as! UITabBarItem).badgeValue = "2"

    // for last tab
    (tabBarController!.tabBar.items!.last! as! UITabBarItem).badgeValue = "final"

对于来自UITabBarItemremovebadge,只需分配nil

(tabBarController!.tabBar.items!.first! as! UITabBarItem).badgeValue = nil

你可以得到输出 Like

更多信息请参考link

选择--2

    var lbl : UILabel = UILabel(frame: CGRectMake(225, 5, 20, 20))
    lbl.layer.borderColor = UIColor.whiteColor().CGColor
    lbl.layer.borderWidth = 2
    lbl.layer.cornerRadius = lbl.bounds.size.height/2
    lbl.textAlignment = NSTextAlignment.Center
    lbl.layer.masksToBounds = true
    lbl.font = UIFont(name: hereaddyourFontName, size: 13)
    lbl.textColor = UIColor.whiteColor()
    lbl.backgroundColor = UIColor.redColor()
    lbl.text = "1"  //if you no need remove this

    // add subview to tabBarController?.tabBar
    self.tabBarController?.tabBar.addSubview(lbl)

输出是

【讨论】:

  • 圆内不需要任何数字,我只想要一个红色的小圆。
  • 对于选项 2,您如何选择要添加徽章的项目。
  • 我来晚了,但如果有人有兴趣知道他如何将徽章应用到预期的项目中,我应该留个便条。实际上,他并没有选择 tabBarItem,而是针对 tabBar 本身。该位置由 CGRectMake 坐标定义。例如,如果您想要最后一个项目,它将类似于 CGRectMake(300, 5, 20, 20)。但我不知道它如何在不同的屏幕上工作,所以我会选择第一个选项
【解决方案2】:

你可以试试这个方法:

func addRedDotAtTabBarItemIndex(index: Int) {

    for subview in tabBarController!.tabBar.subviews {

        if let subview = subview as? UIView {

            if subview.tag == 1314 {
                subview.removeFromSuperview()
                break
            }
        }
    }
    let RedDotRadius: CGFloat = 5
    let RedDotDiameter = RedDotRadius * 2

    let TopMargin:CGFloat = 5

    let TabBarItemCount = CGFloat(self.tabBarController!.tabBar.items!.count)

    let HalfItemWidth = CGRectGetWidth(view.bounds) / (TabBarItemCount * 2)

    let  xOffset = HalfItemWidth * CGFloat(index * 2 + 1)

    let imageHalfWidth: CGFloat = (self.tabBarController!.tabBar.items![index] as! UITabBarItem).selectedImage.size.width / 2

    let redDot = UIView(frame: CGRect(x: xOffset + imageHalfWidth, y: TopMargin, width: RedDotDiameter, height: RedDotDiameter))

    redDot.tag = 1314
    redDot.backgroundColor = UIColor.redColor()
    redDot.layer.cornerRadius = RedDotRadius


    self.tabBarController?.tabBar.addSubview(redDot)
}

【讨论】:

  • 我们应该在故事板中将什么标记为 1314
  • 什么是 view.bounds
【解决方案3】:

我想出了一个破解解决方案。

func addRedDotAtTabBarItemIndex(index: Int,dotRadius: CGFloat) {

    var tabBarButtons = [UIView]()

    // find the UITabBarButton instance.
    for subview in tabBarController!.tabBar.subviews.reverse() {

        if subview.isKindOfClass(NSClassFromString("UITabBarButton")) {

            tabBarButtons.append(subview as! UIView)
        }
    }

    if index >= tabBarButtons.count {
        println("out of bounds")
        return
    }

    let tabBar = tabBarButtons[index]

    var selectedImageWidth: CGFloat!
    var topMargin: CGFloat!

    for subview in tabBar.subviews {

        if subview.isKindOfClass(NSClassFromString("UITabBarSwappableImageView")) {

            selectedImageWidth = (subview as! UIView).frame.size.width
            topMargin = (subview as! UIView).frame.origin.y
        }
    }

    // remove existing red dot.
    for subview in tabBar.subviews {

        if subview.tag == 999 {
            subview.removeFromSuperview()
        }
    }

    let redDot = UIView(frame: CGRect(x: CGRectGetMidX(tabBar.bounds) + selectedImageWidth / 2 + dotRadius, y: topMargin, width: dotRadius * 2, height: dotRadius * 2))

    redDot.backgroundColor = UIColor.redColor()
    redDot.layer.cornerRadius = dotRadius   // half of the view's height.
    redDot.tag = 999

    tabBar.addSubview(redDot)

}

【讨论】:

    【解决方案4】:

    我测试这个问题的答案。但不适用于 iPad。 现在我发现,当你在iPhone上添加这个时,tabBarItem左右边距为2,每个项目边距为4。代码如下:

        NSInteger barItemCount = self.tabBar.items.count;
    
        UITabBarItem *barItem = (UITabBarItem *)self.tabBar.items[index];
        CGFloat imageHalfWidth = barItem.image.size.width / 2.0;
    
        CGFloat barItemWidth = (BXS_WINDOW_WIDTH - barItemCount * 4) / barItemCount;
        CGFloat barItemMargin = 4;
        CGFloat redDotXOffset = barItemMargin / 2 + barItemMargin * index + barItemWidth * (index + 0.5);
    

    和 iPad 如下:

        barItemWidth = 76;
        barItemMargin = 34;
        redDotXOffset = (BXS_WINDOW_WIDTH - 76 * barItemCount - 34 * (barItemCount - 1)) / 2.0 + 76 * (index + 0.5) + 34 * index;
    

    希望这是有用的。

    【讨论】:

      【解决方案5】:

      适用于 iPad 和 iPhone。 能够自动隐藏和计算索引。

      如果 self 不是 UITabBarController,则调用 self.setTabBarDotVisible(visible:true)。

      如果 self 是 UITabBarController,则调用 self.setTabBarDotVisible(visible:true, index:2)。

      import UIKit
      
      public extension UIViewController {
      
      func setTabBarDotVisible(visible:Bool,index: Int? = nil) {
      
          let tabBarController:UITabBarController!
      
          if self is UITabBarController
          {
              tabBarController = self as! UITabBarController
          }
          else
          {
              if self.tabBarController == nil
              {
                  return
              }
              tabBarController = self.tabBarController!
          }
      
          let indexFinal:Int
      
          if (index != nil)
          {
              indexFinal = index!
          }
          else
          {
              let index3 = tabBarController.viewControllers?.index(of: self)
      
              if index3 == nil
              {
                  return;
              }
              else
              {
                   indexFinal = index3!
              }
      
          }
      
          guard let barItems = tabBarController.tabBar.items else
          {
              return
          }
      
          //
      
      
          let tag = 8888
      
          var tabBarItemView:UIView?
      
          for subview in tabBarController.tabBar.subviews {
      
              let className = String(describing: type(of: subview))
      
              guard className == "UITabBarButton" else {
                  continue
              }
      
              var label:UILabel?
              var dotView:UIView?
      
              for subview2 in subview.subviews {
      
                  if subview2.tag == tag {
                      dotView = subview2;
                  }
                  else if (subview2 is UILabel)
                  {
                      label = subview2 as? UILabel
                  }
      
              }
      
      
              if label?.text == barItems[indexFinal].title
              {
                  dotView?.removeFromSuperview()
                  tabBarItemView = subview;
                  break;
              }
          }
      
          if (tabBarItemView == nil || !visible)
          {
              return
          }
      
      
      
          let barItemWidth = tabBarItemView!.bounds.width
      
          let x = barItemWidth * 0.5 + (barItems[indexFinal].selectedImage?.size.width ?? barItemWidth) / 2
          let y:CGFloat = 5
          let size:CGFloat = 10;
      
          let redDot = UIView(frame: CGRect(x: x, y: y, width: size, height: size))
      
          redDot.tag = tag
          redDot.backgroundColor = UIColor.red
          redDot.layer.cornerRadius = size/2
      
      
          tabBarItemView!.addSubview(redDot)
      }
      
      }
      

      【讨论】:

        【解决方案6】:

        这是 Swift 4 解决方案:

        1) 将 BaseTabBar 自定义类添加到您的项目中:

        import UIKit
        
        class BaseTabBar: UITabBar {
          static var dotColor: UIColor = UIColor.red
          static var dotSize: CGFloat = 4
          static var dotPositionX: CGFloat = 0.8
          static var dotPositionY: CGFloat = 0.2
        
          var dotMap = [Int: Bool]()
        
          func resetDots() {
            dotMap.removeAll()
          }
        
          func addDot(tabIndex: Int) {
            dotMap[tabIndex] = true
          }
        
          func removeDot(tabIndex: Int) {
            dotMap[tabIndex] = false
          }
        
          override func draw(_ rect: CGRect) {
            super.draw(rect)
            if let items = items {
              for i in 0..<items.count {
                let item = items[i]
                if let view = item.value(forKey: "view") as? UIView, let dotBoolean = dotMap[i], dotBoolean == true {
                  let x = view.frame.origin.x + view.frame.width * BaseTabBar.dotPositionX
                  let y = view.frame.origin.y + view.frame.height * BaseTabBar.dotPositionY
                  let dotPath = UIBezierPath(ovalIn: CGRect(x: x, y: y, width: BaseTabBar.dotSize, height: BaseTabBar.dotSize))
                  BaseTabBar.dotColor.setFill()
                  dotPath.fill()
                }
              }
            }
          }
        
        }
        

        2) 将 UITabBarController 中的 UITabBar 自定义类更改为 BaseTabBar。

        3)管理可以访问tabBarController的地方的点

        func updateNotificationCount(count: Int) {
            if let tabBar = navigationController?.tabBarController?.tabBar as? BaseTabBar {
              if count > 0 {
                tabBar.addDot(tabIndex: 0)
              } else {
                tabBar.removeDot(tabIndex: 0)
              }
              tabBar.setNeedsDisplay()
            }
          }
        

        【讨论】:

        • 在 ios 15 setNeedsDisplay 使标签栏变成黑色,当使用 addSubView(tableVIew,CollectionView...)
        【解决方案7】:

        我添加了 5 个标签栏索引,并根据通知发生添加点。首先,创建 Dots 视图数组。

        var Dots = [UIView](repeating: UIView(), count: 5)
        
        func addRedDotAtTabBarItemIndex(index: Int) {
        
            if  self.Dots[index].tag != index {
        
                let RedDotRadius: CGFloat = 7
                let RedDotDiameter = RedDotRadius
        
                let TopMargin:CGFloat = 2
        
                let tabSize = self.tabBarController.view.frame.width / CGFloat(5)
        
                let  xPosition = tabSize * CGFloat(index - 1)
        
                let tabHalfWidth: CGFloat = tabSize / 2
        
                self.Dots[index] =  UIView(frame: CGRect(x: xPosition + tabHalfWidth - 2 , y: TopMargin, width: RedDotDiameter, height: RedDotDiameter))
        
                self.Dots[index].tag = index
                self.Dots[index].backgroundColor = UIColor.red
                self.Dots[index].layer.cornerRadius = RedDotRadius
        
                self.tabBarController.tabBar.addSubview(self.Dots[index])
        
            }
        }
        

        如果要从选定索引中删除点,请使用以下代码:

        func removeRedDotAtTabBarItemIndex(index: Int) {
        
                self.Dots[index].removeFromSuperview()
                self.Dots[index].tag = 0
            }
        

        【讨论】:

          【解决方案8】:

          如果你想避免遍历子视图和潜在的危险黑客攻击,我所做的就是将徽章的背景颜色设置为清除并使用带样式的项目符号点显示为徽章:

          tabBarItem.badgeValue = "●"
          tabBarItem.badgeColor = .clear
          tabBarItem.setBadgeTextAttributes([NSAttributedStringKey.foregroundColor.rawValue: UIColor.red], for: .normal)
          

          这似乎比其他答案更具前瞻性。

          【讨论】:

          • 最简单、最智能的解决方案。谢谢!
          • 这个解决方案太棒了!谢谢!
          • 这太棒了。但是,如果您在徽章定位方面遇到问题并且不想使用任何技巧,请在此处查看这个家伙的答案:stackoverflow.com/a/53531046/1161412
          • 在 ios 15 中这会在这个点内返回更多点
          【解决方案9】:

          简单的解决方案 在情节提要 tabbaritem 徽章值中设置空间。

          如果我们在输出下方添加空格,您可以获得:

          【讨论】:

            【解决方案10】:

            这在当前的iOS 版本中非常简单

            tabBarItem.badgeValue = " "
            

            它显示tabbar item顶部的红点

            【讨论】:

            • 这在 ios 15 中形成了大圈
            【解决方案11】:

            在 Swift 5 中:

            tabBarItem.badgeValue = "1"
            

            改变默认颜色使用:

            tabBarItem.badgeColor = UIColor.systemBlue
            

            【讨论】:

              【解决方案12】:

              斯威夫特 5+

              这进入属于该选项卡的控制器

              替代。你只需要抓住正确的tabBarItem

              func updateTabBarBadge(showDot: Bool) {
                  
                  guard let tbi = tabBarItem else {
                      return
                  }
                  
                  if showDot {
                      tbi.setBadgeTextAttributes([.font: UIFont.systemFont(ofSize: 6), .foregroundColor:UIColor(named: "Primary")!], for: .normal)
                      tbi.badgeValue = "⬤"
                      tbi.badgeColor = UIColor.clear
                  } else {
                      tbi.badgeValue = nil
                  }
                  
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-12-04
                • 2014-07-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多