133 lines
4.3 KiB
Swift
133 lines
4.3 KiB
Swift
//
|
|
// LineSpaceLabel.swift
|
|
// Crush
|
|
//
|
|
// Created by Leon on 2025/7/18.
|
|
//
|
|
import UIKit
|
|
|
|
class LineSpaceLabel: UILabel {
|
|
// MARK: - Properties
|
|
|
|
var paragraphSpace: CGFloat = 0
|
|
|
|
private var typography: EPTypography?
|
|
private var typographyText: String?
|
|
|
|
// MARK: - Initialization
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
numberOfLines = 0
|
|
textColor = .text
|
|
guard let text = typographyText, !text.isEmpty else { return }
|
|
self.text = text
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
// MARK: - Public Methods (Way 1)
|
|
|
|
func setupLineSpace(_ space: CGFloat) {
|
|
guard let text = text, !text.isEmpty else {
|
|
assertionFailure("self.text should not be empty.")
|
|
return
|
|
}
|
|
|
|
let attributedString: NSMutableAttributedString
|
|
if let existingAttributedText = attributedText {
|
|
attributedString = NSMutableAttributedString(attributedString: existingAttributedText)
|
|
} else {
|
|
attributedString = NSMutableAttributedString(string: text)
|
|
}
|
|
|
|
let paragraphStyle = NSMutableParagraphStyle()
|
|
paragraphStyle.lineSpacing = space
|
|
attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: text.count))
|
|
|
|
self.text = nil
|
|
attributedText = attributedString
|
|
lineBreakMode = .byTruncatingTail
|
|
}
|
|
|
|
func setupText(_ text: String?, lineSpace: CGFloat) {
|
|
let safeText = text ?? ""
|
|
|
|
let attributedString = NSMutableAttributedString(string: safeText)
|
|
let paragraphStyle = NSMutableParagraphStyle()
|
|
paragraphStyle.lineSpacing = lineSpace
|
|
attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: safeText.count))
|
|
|
|
attributedText = attributedString
|
|
lineBreakMode = .byTruncatingTail
|
|
}
|
|
|
|
func setupHighlightText(_ highlight: String?, color: UIColor) {
|
|
guard let attributedText = attributedText, let highlight = highlight, !highlight.isEmpty else {
|
|
assertionFailure("attributedText and highlight must be valid")
|
|
return
|
|
}
|
|
|
|
let attributedString = NSMutableAttributedString(attributedString: attributedText)
|
|
if let range = attributedString.string.range(of: highlight) {
|
|
let nsRange = NSRange(range, in: attributedString.string)
|
|
attributedString.addAttribute(.foregroundColor, value: color, range: nsRange)
|
|
}
|
|
self.attributedText = attributedString
|
|
}
|
|
|
|
// MARK: - Public Methods (Way 2)
|
|
|
|
func config(_ typography: EPTypography) {
|
|
self.typography = typography
|
|
self.text = text
|
|
}
|
|
|
|
// MARK: - Overrides
|
|
|
|
override var text: String? {
|
|
get { super.text }
|
|
set {
|
|
let safeText = newValue ?? ""
|
|
|
|
if let typography = typography {
|
|
typographyText = safeText
|
|
let attributes: [NSAttributedString.Key: Any] = [
|
|
.font: typography.font!,
|
|
.foregroundColor: textColor ?? .black,
|
|
]
|
|
let attributedString = NSMutableAttributedString(string: safeText, attributes: attributes)
|
|
|
|
let calLineHeight = typography.lineHeight * 0.5 // Temporary conversion, may need testing
|
|
let paragraphStyle = NSMutableParagraphStyle()
|
|
paragraphStyle.lineSpacing = calLineHeight
|
|
paragraphStyle.alignment = textAlignment
|
|
if paragraphSpace > 0 {
|
|
paragraphStyle.paragraphSpacing = paragraphSpace
|
|
}
|
|
attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: safeText.count))
|
|
|
|
self.attributedText = attributedString
|
|
self.lineBreakMode = .byTruncatingTail
|
|
|
|
layoutIfNeeded()
|
|
} else {
|
|
super.text = safeText
|
|
}
|
|
}
|
|
}
|
|
|
|
override var textColor: UIColor! {
|
|
get { super.textColor }
|
|
set {
|
|
super.textColor = newValue
|
|
if let typographyText = typographyText, !typographyText.isEmpty {
|
|
text = typographyText
|
|
}
|
|
}
|
|
}
|
|
}
|