如何在UITabBarItem中添加小红点

问题描述 投票:0回答:16

如何在

UITabBarItem
的右上角添加红点。 enter image description here

我搜索了一段时间,有些人说这可以通过设置

UITabBarItem
的徽章值来完成。但是当我尝试将徽章值设置为空白“”时,红点有点大。我该怎么办得到一个合适的吗?非常感谢。

enter image description here

ios swift uitabbaritem badge
16个回答
63
投票

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

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

这似乎比其他答案更面向未来。


31
投票

你可以试试这个方法:

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

8
投票

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

    // 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"

对于

remove
来自
badge
UITabBarItem
只需分配
nil

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

你可以获得像

这样的输出

enter image description here

欲了解更多信息,请参考此链接

选择--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)

输出是

enter image description here


5
投票

这在当前的

iOS
版本中非常简单

tabBarItem.badgeValue = " "

它显示了

tabbar item

顶部的红点

3
投票

斯威夫特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
    }
    
}

1
投票

我已经找到了一个黑客解决方案。

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)

}

1
投票

适用于 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)
}

}

0
投票

我测试这个问题的答案。但不适用于 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;

希望这有用。


0
投票

这是 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()
    }
  }

0
投票

我添加了 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
    }

0
投票

简单的解决方案 在故事板 tabbaritem 徽章值中设置空间。

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


0
投票

在 Swift 5 中:

tabBarItem.badgeValue = "1"

要更改默认颜色使用:

tabBarItem.badgeColor = UIColor.systemBlue

0
投票

从 iOS 13 开始,使用

UITabBarAppearance
UITabBarItemAppearance

let appearance = UITabBarAppearance()

let itemAppearance = UITabBarItemAppearance(style: .stacked)
itemAppearance.normal.badgeBackgroundColor = .clear
itemAppearance.normal.badgeTextAttributes = [.foregroundColor: UIColor.red]

profileViewController.tabBarItem.badgeValue = "●"

0
投票

快速用户界面

@PeterLapisu 对 Swift-UI 的回答

UITabBarItem.appearance().badgeColor = UIColor(Color.clear)
UITabBarItem.appearance().setBadgeTextAttributes(
    [
        .foregroundColor: UIColor(Color.red)
    ]
    , for: .normal)

选项卡上的项目:

.badge(showBadge ? "●" : nil)

0
投票

在特定选项卡上添加删除徽章:

func setTabbarBadgeForTabIndex(tabIndex: Int, isBadged: Bool) {
    let badgeTag = 6660 + tabIndex

    // remove badge
    guard isBadged else {
        tabBar.subviews.first { $0.tag == badgeTag }?.removeFromSuperview()
        return
    }
    
    //check if badge already exist
    if tabBar.subviews.first(where: { $0.tag == badgeTag }) != nil {
        return
    }

    let tabCount = viewControllers?.count ?? 0
    let tabBarWidth = Int(tabBar.frame.width)
    let leftMargin = 2
    let rightMargin = 2
    let betweenMargin = 4
    let netWidth = tabBarWidth - leftMargin * 2

    let tabItemWidth = (netWidth - betweenMargin * (tabCount - 1)) / tabCount
    let dotDiameter = 8

    let xOffset = leftMargin + tabItemWidth + tabIndex * (betweenMargin + tabItemWidth) - tabItemWidth / 4 - dotDiameter / 2

    let redDot = UIView(frame: CGRect(x: xOffset, y: 2, width: dotDiameter, height: dotDiameter))
    redDot.layer.cornerRadius = CGFloat(dotDiameter / 2)
    redDot.backgroundColor = .red
    redDot.tag = badgeTag

    tabBar.addSubview(redDot)
}

-1
投票
let appearance = UITabBarAppearance()

let itemAppearance = UITabBarItemAppearance(style: .stacked)
itemAppearance.normal.badgeBackgroundColor = .clear
itemAppearance.normal.badgeTextAttributes = [.font: UIFont.systemFont(ofSize: 50), .foregroundColor: UIColor.green]

yourViewController.tabBarItem.badgeValue = "●"
// if you want to remove badge from tab then set nil
yourViewController.tabBarItem.badgeValue = nil

结果

© www.soinside.com 2019 - 2024. All rights reserved.