Last active
September 3, 2023 09:14
-
-
Save Marcocanc/157dae2ae5976de28b3e3020fdff01d5 to your computer and use it in GitHub Desktop.
A UILabel subclass that can hold attributes and apply them to text
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
/// A UILabel subclass that can hold attributes and apply them to text | |
@IBDesignable | |
final class Label: UILabel { | |
convenience init(attributes: [NSAttributedStringKey: Any]) { | |
self.init() | |
self.attributes = attributes | |
} | |
// MARK: Properties | |
/// The attributes for the attributed string. | |
var attributes: [NSAttributedStringKey: Any] = [:] { | |
didSet { | |
guard let existingString = super.attributedText?.string else { return } | |
super.attributedText = NSAttributedString(string: existingString, attributes: attributes) | |
} | |
} | |
/// The current text that is displayed by the label. | |
override var text: String? { | |
set { super.attributedText = NSAttributedString(string: newValue ?? "", attributes: attributes) } | |
get { return super.attributedText?.string } | |
} | |
/// The font used to display the text. | |
override var font: UIFont! { | |
get { return attributes[.font] as? UIFont ?? .systemFont(ofSize: 17) } | |
set { attributes[.font] = newValue } | |
} | |
/// The color of the text. | |
override var textColor: UIColor! { | |
get { return attributes[.foregroundColor] as? UIColor ?? .black } | |
set { attributes[.foregroundColor] = newValue } | |
} | |
/// The text alignment of the receiver. | |
override var textAlignment: NSTextAlignment { | |
get { return paragraphStyle?.alignment ?? .natural } | |
set { setParagraphValue(newValue, for: \.alignment) } | |
} | |
/// The mode that should be used to break lines in the receiver. | |
override var lineBreakMode: NSLineBreakMode { | |
get { return paragraphStyle?.lineBreakMode ?? .byWordWrapping } | |
set { setParagraphValue(newValue, for: \.lineBreakMode) } | |
} | |
/// The distance in points between the bottom of one line fragment and the top of the next. | |
var lineSpacing: CGFloat { | |
get { return paragraphStyle?.lineSpacing ?? 0.0 } | |
set { setParagraphValue(newValue, for: \.lineSpacing) } | |
} | |
/// The receiver’s minimum height. | |
@IBInspectable | |
var minimumLineHeight: CGFloat { | |
get { return paragraphStyle?.minimumLineHeight ?? 0 } | |
set { setParagraphValue(newValue, for: \.minimumLineHeight) } | |
} | |
/// The receiver’s maximum height. | |
@IBInspectable | |
var maximumLineHeight: CGFloat { | |
get { return paragraphStyle?.maximumLineHeight ?? 0 } | |
set { setParagraphValue(newValue, for: \.maximumLineHeight) } | |
} | |
/// The natural line height of the receiver is multiplied by this factor (if positive) before being constrained by minimum and maximum line height. | |
@IBInspectable | |
var lineHeightMultiple: CGFloat { | |
get { return paragraphStyle?.lineHeightMultiple ?? 0 } | |
set { setParagraphValue(newValue, for: \.lineHeightMultiple) } | |
} | |
/// This value specifies the number of points by which to adjust kern-pair characters. | |
@IBInspectable | |
var kern: CGFloat { | |
get { return attributes[.kern] as? CGFloat ?? 0 } | |
set { attributes[.kern] = newValue } | |
} | |
// MARK: Private | |
private var paragraphStyle: NSMutableParagraphStyle? { | |
return attributes[.paragraphStyle] as? NSMutableParagraphStyle | |
} | |
/// Sets a value at the specified KeyPath of ParagraphStyle. | |
private func setParagraphValue<T>(_ value: T, for keyPath: ReferenceWritableKeyPath<NSMutableParagraphStyle, T>) { | |
let style = paragraphStyle ?? NSMutableParagraphStyle() | |
style[keyPath: keyPath] = value | |
attributes[.paragraphStyle] = style | |
} | |
// MARK: Unavailable | |
@available(*, unavailable) | |
override var attributedText: NSAttributedString? { willSet { } } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment