Swift 将徽章添加到导航栏ButtonItem 和 UIButton [英] Swift add badge to navigation barButtonItem and UIButton

查看:34
本文介绍了Swift 将徽章添加到导航栏ButtonItem 和 UIButton的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在我的通知按钮上显示徽章,在 AppIcon 上显示的应用程序中.

到目前为止,我所研究的一切都与 Obj 有关.C,但没有专门讨论将该解决方案实现到 Swift 中的方法,

请帮助找到添加自定义类/代码以在 UiBarbutton 和 UiButton 上实现 Badge 的解决方案.

迄今为止的研究:

https://github.com/Marxon13/M13BadgeView

连同 MKBadge 类等

解决方案

有一个更优雅的解决方案,带有 UIButtonItem 的扩展

extension CAShapeLayer {func drawCircleAtLocation(location: CGPoint, withRadius radius: CGFloat, andColor color: UIColor, Filled: Bool) {填充颜​​色 = 填充?color.cgColor : UIColor.white.cgColorstrokeColor = color.cgColor让 origin = CGPoint(x: location.x - 半径, y: location.y - 半径)path = UIBezierPath(ovalIn: CGRect(origin: origin, size: CGSize(width: radius * 2, height: radius * 2))).cgPath}}私有变量句柄:UInt8 = 0扩展 UIBarButtonItem {私有 var 徽章层:CAShapeLayer?{if let b: AnyObject = objc_getAssociatedObject(self, &handle) as AnyObject?{返回 b 作为?CAShape图层} 别的 {返回零}}func addBadge(number: Int, withOffset offset: CGPoint = CGPoint.zero, andColor color: UIColor = UIColor.red, andFilled Filled: Bool = true) {守卫 let view = self.value(forKey: "view") as?UIView 其他 { 返回 }徽章层?.removeFromSuperlayer()//初始化徽章让徽章 = CAShapeLayer()让半径 = CGFloat(7)让 location = CGPoint(x: view.frame.width - (radius + offset.x), y: (radius + offset.y))徽章.drawCircleAtLocation(位置:位置,withRadius:半径,和颜色:颜色,填充:填充)view.layer.addSublayer(徽章)//初始化徽章的标签让标签 = CATextLayer()label.string = "\(数字)"label.alignmentMode = CATextLayerAlignmentMode.centerlabel.fontSize = 11label.frame = CGRect(origin: CGPoint(x: location.x - 4, y: offset.y), size: CGSize(width: 8, height: 16))label.foregroundColor = 填充?UIColor.white.cgColor : color.cgColorlabel.backgroundColor = UIColor.clear.cgColorlabel.contentsScale = UIScreen.main.scale徽章.addSublayer(标签)//将徽章保存为 UIBarButtonItem 属性objc_setAssociatedObject(自我,&句柄,徽章,.OBJC_ASSOCIATION_RETAIN_NONATOMIC)}func updateBadge(number: Int) {如果让文本 = 徽章层?.sublayers?.filter({ $0 is CATextLayer }).first as?CATextLayer {text.string = "\(数字)"}}func removeBadge() {徽章层?.removeFromSuperlayer()}}

这个很棒的代码是由 Stefano Vettor 创建的,您可以在以下位置找到所有详细信息:https://gist.github.com/freedom27/c709923b163e26405f637a2439p

I am trying to display badge on my notification button, in app as displayed on AppIcon.

So far whatever i have researched is related to Obj. C, but nothing that specifically discussed way to implement that solution into Swift,

Please help to find a solution to add a custom class / code to achieve Badge on UiBarbutton and UiButton.

Researched so far:

https://github.com/Marxon13/M13BadgeView

along with MKBadge class etc.

解决方案

There is a more elegant solution with an extension for UIButtonItem

extension CAShapeLayer {
    func drawCircleAtLocation(location: CGPoint, withRadius radius: CGFloat, andColor color: UIColor, filled: Bool) {
        fillColor = filled ? color.cgColor : UIColor.white.cgColor
        strokeColor = color.cgColor
        let origin = CGPoint(x: location.x - radius, y: location.y - radius)
        path = UIBezierPath(ovalIn: CGRect(origin: origin, size: CGSize(width: radius * 2, height: radius * 2))).cgPath
    }
}

private var handle: UInt8 = 0

extension UIBarButtonItem {
    private var badgeLayer: CAShapeLayer? {
        if let b: AnyObject = objc_getAssociatedObject(self, &handle) as AnyObject? {
            return b as? CAShapeLayer
        } else {
            return nil
        }
    }

    func addBadge(number: Int, withOffset offset: CGPoint = CGPoint.zero, andColor color: UIColor = UIColor.red, andFilled filled: Bool = true) {
        guard let view = self.value(forKey: "view") as? UIView else { return }

        badgeLayer?.removeFromSuperlayer()

        // Initialize Badge
        let badge = CAShapeLayer()
        let radius = CGFloat(7)
        let location = CGPoint(x: view.frame.width - (radius + offset.x), y: (radius + offset.y))
        badge.drawCircleAtLocation(location: location, withRadius: radius, andColor: color, filled: filled)
        view.layer.addSublayer(badge)

        // Initialiaze Badge's label
        let label = CATextLayer()
        label.string = "\(number)"
        label.alignmentMode = CATextLayerAlignmentMode.center
        label.fontSize = 11
        label.frame = CGRect(origin: CGPoint(x: location.x - 4, y: offset.y), size: CGSize(width: 8, height: 16))
        label.foregroundColor = filled ? UIColor.white.cgColor : color.cgColor
        label.backgroundColor = UIColor.clear.cgColor
        label.contentsScale = UIScreen.main.scale
        badge.addSublayer(label)

        // Save Badge as UIBarButtonItem property
        objc_setAssociatedObject(self, &handle, badge, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }

    func updateBadge(number: Int) {
        if let text = badgeLayer?.sublayers?.filter({ $0 is CATextLayer }).first as? CATextLayer {
            text.string = "\(number)"
        }
    }

    func removeBadge() {
        badgeLayer?.removeFromSuperlayer()
    }
}

This great code was created by Stefano Vettor and you can find all the details at: https://gist.github.com/freedom27/c709923b163e26405f62b799437243f4

这篇关于Swift 将徽章添加到导航栏ButtonItem 和 UIButton的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆