如何在UITabBarItem中添加小红点
How to add small red dot in UITabBarItem
如何在 UITabBarItem
的右上角添加红点。
我搜索了一段时间,有些人说这可以通过设置 UITabBarItem
的徽章值来完成。但是当我尝试将徽章值设置为空时 space " ",红点有点big.How能给我一个合适的吗?非常感谢
为您想要的 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"
对于 remove
来自 UITabBarItem
的 badge
只需分配 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)
输出是
你可以试试这个方法:
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)
}
我找到了破解方法。
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)
}
我测试这个问题的答案。但不适用于 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;
希望这有用。
适用于 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)
}
}
这个吧 Swift 4 解法:
1) 添加 BaseTabBar 自定义 class 到您的项目:
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 的自定义 class 更改为 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()
}
}
我添加了5个tab bar索引,并根据通知的出现添加圆点。首先,创建点视图数组。
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
}
如果您想避免遍历子视图和一般的潜在危险黑客,我所做的是将徽章的背景色设置为清除并使用样式化的项目符号点显示为徽章:
tabBarItem.badgeValue = "●"
tabBarItem.badgeColor = .clear
tabBarItem.setBadgeTextAttributes([NSAttributedStringKey.foregroundColor.rawValue: UIColor.red], for: .normal)
这似乎比其他答案更具前瞻性。
简单的解决方案
在故事板 tabbaritem 徽章值中设置 space。
如果我们在输出下面添加 space 你可以得到:
这在当前 iOS
版本中非常简单
tabBarItem.badgeValue = " "
显示 tabbar item
顶部的红点
在Swift 5:
tabBarItem.badgeValue = "1"
更改默认颜色使用:
tabBarItem.badgeColor = UIColor.systemBlue
Swift 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
}
}
从iOS13开始,使用UITabBarAppearance
和UITabBarItemAppearance
let appearance = UITabBarAppearance()
let itemAppearance = UITabBarItemAppearance(style: .stacked)
itemAppearance.normal.badgeBackgroundColor = .clear
itemAppearance.normal.badgeTextAttributes = [.foregroundColor: UIColor.red]
profileViewController.tabBarItem.badgeValue = "●"
如何在 UITabBarItem
的右上角添加红点。
我搜索了一段时间,有些人说这可以通过设置 UITabBarItem
的徽章值来完成。但是当我尝试将徽章值设置为空时 space " ",红点有点big.How能给我一个合适的吗?非常感谢
为您想要的 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"
对于 remove
来自 UITabBarItem
的 badge
只需分配 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)
输出是
你可以试试这个方法:
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)
}
我找到了破解方法。
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)
}
我测试这个问题的答案。但不适用于 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;
希望这有用。
适用于 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)
}
}
这个吧 Swift 4 解法:
1) 添加 BaseTabBar 自定义 class 到您的项目:
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 的自定义 class 更改为 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()
}
}
我添加了5个tab bar索引,并根据通知的出现添加圆点。首先,创建点视图数组。
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
}
如果您想避免遍历子视图和一般的潜在危险黑客,我所做的是将徽章的背景色设置为清除并使用样式化的项目符号点显示为徽章:
tabBarItem.badgeValue = "●"
tabBarItem.badgeColor = .clear
tabBarItem.setBadgeTextAttributes([NSAttributedStringKey.foregroundColor.rawValue: UIColor.red], for: .normal)
这似乎比其他答案更具前瞻性。
简单的解决方案 在故事板 tabbaritem 徽章值中设置 space。
如果我们在输出下面添加 space 你可以得到:
这在当前 iOS
版本中非常简单
tabBarItem.badgeValue = " "
显示 tabbar item
在Swift 5:
tabBarItem.badgeValue = "1"
更改默认颜色使用:
tabBarItem.badgeColor = UIColor.systemBlue
Swift 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
}
}
从iOS13开始,使用UITabBarAppearance
和UITabBarItemAppearance
let appearance = UITabBarAppearance()
let itemAppearance = UITabBarItemAppearance(style: .stacked)
itemAppearance.normal.badgeBackgroundColor = .clear
itemAppearance.normal.badgeTextAttributes = [.foregroundColor: UIColor.red]
profileViewController.tabBarItem.badgeValue = "●"