UILabel在设置背景颜色的时候,四条边是紧贴着文字的,我们想写一个小tag样式的控件(如下图所示)
一般有以下两种实现方式:
- 计算文字宽度和高度,加top、right、bottom、left的间隔,再给label赋值计算后的size
- (一般用于xib/storyboard)文字label+背景view,label为view的子控件,给label设置距离view的内部约束,靠自动布局把view撑开
如果UILabel有Inset属性就会节省一定的开发成本。自定义一个UILabel实现这个功能吧~
class XYInsetLabel: UILabel {
/// 可以设置文字上下左右的边距
var textInsets: UIEdgeInsets = UIEdgeInsets.zero {
didSet {
setNeedsLayout()
}
}
/// 便利构造方法
convenience init(textInsets: UIEdgeInsets = .zero) {
self.init(frame: CGRect.zero)
self.textInsets = textInsets
}
override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
guard !(text?.isEmpty ?? true) else { return super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) }
let addInset = bounds.inset(by: textInsets)
let realRect = super.textRect(forBounds: addInset, limitedToNumberOfLines: numberOfLines)
let invertedInsets = UIEdgeInsets(top: -textInsets.top, left: -textInsets.left, bottom: -textInsets.bottom, right: -textInsets.right)
return realRect.inset(by: invertedInsets)
}
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: textInsets))
}
}
使用示例:
// 设置文字上下边距4,左右边距8
let tagLabel = XYInsetLabel.init(textInsets: UIEdgeInsets(top: 4, left: 8, bottom: 4, right: 8))
// 按照普通label设置其他属性即可
tagLabel.text = "一个tag"
tagLabel.sizeToFit()
tagLabel.layer.masksToBounds = true
tagLabel.layer.cornerRadius = 4
tagLabel.textColor = .red
tagLabel.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.2)
// 不用关心它的宽高,直接设置center就行,label会根据文字和边距自动计算宽高
tagLabel.center = CGPoint(x: 200, y: 200)
view.addSubview(tagLabel)