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

截图

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)
}
大致就这样的,给有需要的朋友可以借鉴一下。
网友评论