iOS 为UILabel添加edgeInset功能

UILabel在设置背景颜色的时候,四条边是紧贴着文字的,我们想写一个小tag样式的控件(如下图所示)


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)
运行效果

你可能感兴趣的:(iOS 为UILabel添加edgeInset功能)