如何为 UITabBar 徽章添加边框?

Posted

技术标签:

【中文标题】如何为 UITabBar 徽章添加边框?【英文标题】:How to add border to UITabBar Badge? 【发布时间】:2018-11-29 10:58:30 【问题描述】:

如何在标签栏项中为徽章添加自定义边框?默认情况下,它在标签栏项目的右上角显示一个红点。我想给它加个边框。有一个选项可以更改徽章的颜色,但我找不到任何可以为徽章添加边框的东西。

【问题讨论】:

【参考方案1】:

我认为没有官方的方法可以为徽章添加边框,但我也想这样做,最终我开发了自己的方法。我的解决方案更像是一个 hack,但它适用于 Xcode 10.1 和 ios 12.1,不会让您的应用被拒绝,所以也许对您来说已经足够了。

最难的部分是真正拿到徽章,这是带有 5 个标签的标签栏的视图层次结构:

您可以看到,在我的项目中,最后一个选项卡包含徽章。但实际上它是第 4 个标签(带有index = 3 的标签),这是因为我在我的 UITabBarController 类中将第 4 个标签放在顶部,因此在显示更大值的情况下不会剪裁徽章。这是我获得徽章视图的方式(这是在 UITabBar 上下文中,所以 self 是 UITabBar):

func badge(forIndex index: Int) -> UIView? 
    let sorted = self.subviews.sorted  (view1, view2) -> Bool in // I need to sort it by the frame.origin.x because the order in the subviews array cannot be trusted, I got random order there during my tests
        return view1.frame.origin.x < view2.frame.origin.x
    
    let idx = index + 1 // the first view is actually a _UIBarBackground
    guard let barItemView = sorted[safe: idx] else 
        print("\(#file):\(#function):\(#line): Could not find a subview with index \(idx) in \(self)")
        return nil
    
    if barItemView.subviews.count == 3  // this is a hack, but I could not find a better way to get the badge without using private interfaces
        let view = barItemView.subviews.last
        return view
    
    return nil

这为您提供了徽章视图,并且在最难(和最丑陋)的部分后面,我们现在可以添加边框(或像我在项目中所做的那样更改位置):

if let badgeView = badge(forIndex: index) 
    // I found that it's easier to transform the layer here instead of the view, because it's instantaneous
    let badgeViewLayer = badgeView.layer
    badgeViewLayer.transform = CATransform3DMakeTranslation(BadgeTranslationX, BadgeTranslationY, 1) // you can change the position of the badge with this

    guard let badgeViewImageView = badgeView.subviews.first else 
        print("\(#file):\(#function):\(#line): No image view inside the badge view")
        return
    

    badgeViewImageView.clipsToBounds = true // this is important, otherwise you may get artifacts when working with rounded corners etc.
    let layer = badgeViewImageView.layer
    layer.borderColor = UIColor.white.cgColor
    layer.borderWidth = 2
    layer.cornerRadius = 8

这是您使用上述代码得到的结果:

当然,颜色可以是任何颜色:

【讨论】:

以上是关于如何为 UITabBar 徽章添加边框?的主要内容,如果未能解决你的问题,请参考以下文章

如何为栏按钮添加徽章?

在应用程序中使用两个不同的 uitab bar

我们如何为多个 UITab 使用相同的 WKWebView

如何为文本添加一些边框? [复制]

如何为 UIPickerView 添加边框?

如何为表单框添加边框?