Created
June 6, 2021 09:49
-
-
Save Catherine-K-George/3bffbf1433b34b630b7bc572d6af9f6d to your computer and use it in GitHub Desktop.
UILabel extension with ReadMore/ ReadLess action
This file contains hidden or 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 | |
enum TrailingContent { | |
case readmore | |
case readless | |
var text: String { | |
switch self { | |
case .readmore: return "...Read More" | |
case .readless: return " Read Less" | |
} | |
} | |
} | |
extension UILabel { | |
private var minimumLines: Int { return 4 } | |
private var highlightColor: UIColor { return .red } | |
private var attributes: [NSAttributedString.Key: Any] { | |
return [.font: self.font ?? .systemFont(ofSize: 18)] | |
} | |
public func requiredHeight(for text: String) -> CGFloat { | |
let label = UILabel(frame: CGRect(x: 0, y: 0, width: frame.width, height: CGFloat.greatestFiniteMagnitude)) | |
label.numberOfLines = minimumLines | |
label.lineBreakMode = NSLineBreakMode.byTruncatingTail | |
label.font = font | |
label.text = text | |
label.sizeToFit() | |
return label.frame.height | |
} | |
func highlight(_ text: String, color: UIColor) { | |
guard let labelText = self.text else { return } | |
let range = (labelText as NSString).range(of: text) | |
let mutableAttributedString = NSMutableAttributedString.init(string: labelText) | |
mutableAttributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: range) | |
self.attributedText = mutableAttributedString | |
} | |
func appendReadmore(after text: String, trailingContent: TrailingContent) { | |
self.numberOfLines = minimumLines | |
let fourLineText = "\n\n\n" | |
let fourlineHeight = requiredHeight(for: fourLineText) | |
let sentenceText = NSString(string: text) | |
let sentenceRange = NSRange(location: 0, length: sentenceText.length) | |
var truncatedSentence: NSString = sentenceText | |
var endIndex: Int = sentenceRange.upperBound | |
let size: CGSize = CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude) | |
while truncatedSentence.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil).size.height >= fourlineHeight { | |
if endIndex == 0 { | |
break | |
} | |
endIndex -= 1 | |
truncatedSentence = NSString(string: sentenceText.substring(with: NSRange(location: 0, length: endIndex))) | |
truncatedSentence = (String(truncatedSentence) + trailingContent.text) as NSString | |
} | |
self.text = truncatedSentence as String | |
self.highlight(trailingContent.text, color: highlightColor) | |
} | |
func appendReadLess(after text: String, trailingContent: TrailingContent) { | |
self.numberOfLines = 0 | |
self.text = text + trailingContent.text | |
self.highlight(trailingContent.text, color: highlightColor) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
guard let text = descLbl.text else { return }