Swift5.x 任意 UIView 角标

UIView 、UIBarButtonItem添加右上角数字角标

UIView+Badge

import UIKit
import Foundation

private var unsafe_badge_raw: Int = 0

struct BadgeConfig {
    var backgroundColor: UIColor = .red
    var font: UIFont = UIFont.systemFont(ofSize: UIFont.smallSystemFontSize)
    var height: CGFloat = 15
    var cornerRadius: CGFloat = 7.5
    var titleColor: UIColor = .white
    var padding:(w: CGFloat, h: CGFloat) = (w: 6, h: 0)
}

extension UIView {
    /// 设置角标
    func setBadgeValue(_ value: String?, _ config: BadgeConfig = BadgeConfig()) {
        // 关联值 目的是可以手动获取到值
        objc_setAssociatedObject(self,
                                 &unsafe_badge_raw,
                                 value,
                                 .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
        guard let badgeValue = value, isAllNumber(string: badgeValue) else {
            clearBadgeValue()
            return
        }
        let size = CGSize.init(width: CGFloat(MAXFLOAT) , height: CGFloat(MAXFLOAT))
        let rect = badgeValue.boundingRect(
            with: size,
            options: .usesLineFragmentOrigin,
            attributes: [.font: UIFont.systemFont(ofSize: UIFont.smallSystemFontSize)],
            context: nil
        )
        let width = rect.size.width > config.height ? rect.size.width + config.padding.w : config.height
        let badgeBtn = UIButton(
            frame: CGRect(x: 0, y: 0, width: width, height: config.height + config.padding.h)
        )
        badgeBtn.center = CGPoint(x: frame.size.width, y: 0)
        badgeBtn.tag = 1008611
        badgeBtn.layer.cornerRadius = config.cornerRadius
        badgeBtn.layer.masksToBounds = true
        badgeBtn.titleLabel?.font = config.font
        badgeBtn.backgroundColor = config.backgroundColor
        badgeBtn.setTitleColor(config.titleColor, for: .normal)
        badgeBtn.setTitle(badgeValue, for: .normal)
        addSubview(badgeBtn)
        bringSubviewToFront(badgeBtn)
    }
    /// 获取badgeValue
    var badgeValue: String? {
        guard let valueStr = objc_getAssociatedObject(self, &unsafe_badge_raw) as? String,
              let value = Int(valueStr)
        else { return nil }
        if value < 0 {
            return "0"
        } else {
            return valueStr
        }
    }
    /// 清除badgeValue
    func clearBadgeValue() {
        for view in subviews {
            if (view is UIButton) && view.tag == 1008611 {
                view.removeFromSuperview()
            }
        }
    }

    /// 判断是否全是数字
    func isAllNumber(string: String) -> Bool {
        let scan: Scanner = Scanner(string: string)
        var val:Int = 0
        return scan.scanInt(&val) && scan.isAtEnd
    }
}

至于使用嘛

let v = UIView.init(frame: CGRect.init(x: 100, y: 100, width: 100, height: 100))
v.backgroundColor = .green
view.addSubview(v)
v.setBadgeValue("10")
print(v.badgeValue)

或者

let v = UIView.init(frame: CGRect.init(x: 100, y: 100, width: 100, height: 100))
v.backgroundColor = .green
view.addSubview(v)
var config = BadgeConfig()
config.backgroundColor = .blue
v.setBadgeValue("10", config)
print(v.badgeValue)

UIBarButtonItem 添加badge

let badge = UIView(frame: CGRect.init(x: 0, y: 0, width: 30, height: 30))
badge.backgroundColor = .green
badge.setBadgeValue("10")

let rightBarButton = UIBarButtonItem(customView: badge)
self.navigationItem.rightBarButtonItem = rightBarButton

你可能感兴趣的:(Swift5.x 任意 UIView 角标)