I'm writing this subclass to add an icon to a UILabel. It works, but I'm wondering if this is the best/cleanest way to do it. Do you see any improvements? Should maybe text
and image
properties be set using a init()
method?
import UIKit
class IconLabel: UILabel {
override var text: String? {
set {
nameLabel.text = newValue
}
get {
return nameLabel.text
}
}
var image: UIImage? {
didSet {
icon.image = image?.withRenderingMode(.alwaysTemplate)
}
}
private lazy var icon: UIImageView = {
let imageView = UIImageView()
imageView.tintColor = .white
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
private lazy var nameLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = Theme.regular(size: .tiny)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = Theme.supportLightGrayColor
self.layer.cornerRadius = 5.0
self.clipsToBounds = true
self.addSubviewsAndConstraints()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func addSubviewsAndConstraints() {
self.addSubview(icon)
self.addSubview(nameLabel)
self.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 5.0, leading: 5.0, bottom: 5.0, trailing: 5.0)
icon.leftAnchor.constraint(equalTo: self.layoutMarginsGuide.leftAnchor).isActive = true
icon.bottomAnchor.constraint(equalTo: self.layoutMarginsGuide.bottomAnchor).isActive = true
icon.heightAnchor.constraint(equalTo: self.layoutMarginsGuide.heightAnchor).isActive = true
icon.widthAnchor.constraint(equalTo: icon.heightAnchor).isActive = true
nameLabel.leftAnchor.constraint(equalTo: icon.rightAnchor, constant: 5.0).isActive = true
nameLabel.centerYAnchor.constraint(equalTo: icon.centerYAnchor).isActive = true
nameLabel.rightAnchor.constraint(equalTo: self.layoutMarginsGuide.rightAnchor).isActive = true
}
}
1 Answer 1
You are using IconLabel
to act as a container, it contains another UILabel
and UIImageView
. There is no need that IconLabel
should be a UILabel
you can just have your label nameLabel
and your imageView icon
in a UIView
container. It means that you need to change :
class IconLabel: UILabel {
to something like
class IconLabelView: UIView {
another note, to keep your custom view generic it's better that you setup the background color outside the class like :
let customView = IconLabelView()
customView.backgroundColor = Theme.supportLightGrayColor
also I think it's better to have two methods for the subview setup and constraints instead of one:
private func addSubviews()
and
private func addConstraints()