UILabelのサブクラスで、textRectを実装すれば実現できる。
class BorderedLabel: UILabel {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
// 枠の色
self.layer.borderColor = UIColor.gray
// 枠の太さ
self.layer.borderWidth = 1.0
// 角丸
self.layer.cornerRadius = 4.0
// 枠内の中心になるように
self.textAlignment = .center
self.clipsToBounds = true
}
override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
var rect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
// 枠とテキスト間のpadding
rect.size.width += 4*2
rect.size.height += 4*2
return rect
}
}
これでsizeThatFitsやintrinsicContentSizeも、枠内のpaddingを考慮したサイズを返し、AutoLayoutの配置もうまくいきます。