button文字图片上下布局以及带角标

最近用swift写了一个上下排版以及带角标的Button,实现还是比较简单的。demo如下图

GIF
badgeBtn.gif
截图
button文字图片上下布局以及带角标_第1张图片
8C1CCEED-9443-4FA9-AA21-56E4E3EB2A59.png

1、首先创建一个UIButton的子类,懒加载一个label

class BadgeBtn: UIButton {
    
    fileprivate lazy var badgeLabel: UILabel = {
        let label = UILabel()
        label.backgroundColor = UIColor.red
        label.textColor = UIColor.white
        label.textAlignment = .center
        return label
    }()

2、重写layoutSubviews方法,在这个方法里面进行图片和文字的上下布局

    override func layoutSubviews() {
        
        super.layoutSubviews()
        if let imageV = imageView,let titleLb = titleLabel {
            //随便给一个string,计算当前font下的label的高度
            let text = "哈罗"
            //string 扩展的一个方法用来计算文字高度和宽度
            let textSize = text.calculateLabelSize(font: (titleLabel?.font.pointSize)!, size: CGSize.init(width: 100, height: 100))
            let imageHeight = self.bounds.height - textSize.height - 5
            imageV.frame = CGRect(x: (self.bounds.width - imageHeight) / 2, y: 0, width: imageHeight, height: imageHeight)
            titleLb.frame = CGRect(x: 0, y: imageV.frame.maxY + 5, width: self.bounds.width, height: textSize.height)
            titleLb.textAlignment = .center
        }
        
    }

3、通过属性观察器来对badgeLabel进行布局以及设置角标

    public var badgeText: String? {
        //当外面调用属性的set方式时会走这个方法
        didSet {
            badgeLabel.text = badgeText
            LayoutBadgeLabel()
        }
    }
    
    fileprivate func LayoutBadgeLabel() {
        //首先判断badge是否已经在button上了,如果在就先移除
        if let _ = badgeLabel.superview {
            badgeLabel.removeFromSuperview()
        }
        guard let bdText = badgeText,let imageV = imageView else { return }
       //string扩展的一个方法,把string转换为int数字,如果num <= 0的话就return,不需要添加badgelabel
        if let badgeNum = bdText.convertStringToInt() {
            if badgeNum <= 0 {
                return
            }
        }
        //根据badgelabel文字font计算size
        var badgeSize = bdText.calculateLabelSize(font: (titleLabel?.font.pointSize)! - 2 , size: CGSize.init(width: 100, height: 100))
        //如果width < height 就把改变width
        if badgeSize.width < badgeSize.height {
            badgeSize.width = badgeSize.height
        }
       //设置badgelabel的位置在image的右上角
        badgeLabel.frame = CGRect(x: imageV.frame.maxX - badgeSize.height / 2 - 1, y: imageV.frame.minY - badgeSize.height / 2 - 1, width: badgeSize.width + 5, height: badgeSize.height + 5)
        badgeLabel.font = UIFont.systemFont(ofSize: (titleLabel?.font.pointSize)! - 2)
        badgeLabel.layer.cornerRadius = (badgeSize.height + 5) / 2
        badgeLabel.clipsToBounds = true
        self.addSubview(badgeLabel)
        
    }

4、使用

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        initializeInterface()
    }
    
    func initializeInterface() {
        let badgebtn = BadgeBtn(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
        badgebtn.setImage(UIImage.init(named: "待评价"), for: .normal)
        badgebtn.setTitle("行程", for: .normal)
        badgebtn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
        badgebtn.setTitleColor(UIColor.black, for: .normal)
       //设置角标
        badgeBtn.badgeText = "66"
        view.addSubview(badgebtn)
    }

大致就这样的,给有需要的朋友可以借鉴一下。

你可能感兴趣的:(button文字图片上下布局以及带角标)