Skip to content

Instantly share code, notes, and snippets.

@Catherine-K-George
Created June 6, 2021 09:49
Show Gist options
  • Save Catherine-K-George/3bffbf1433b34b630b7bc572d6af9f6d to your computer and use it in GitHub Desktop.
Save Catherine-K-George/3bffbf1433b34b630b7bc572d6af9f6d to your computer and use it in GitHub Desktop.
UILabel extension with ReadMore/ ReadLess action
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)
}
}
@wolfxpertlab
Copy link

guard let text = descLbl.text else { return }

    let readmore = (text as NSString).range(of: TrailingContent.readmore.text)
    let readless = (text as NSString).range(of: TrailingContent.readless.text)
    
    print("check Sender CLick" ,sender.didTap(label: descLbl, inRange: readmore))
    
    if sender.didTap(label: descLbl, inRange: readmore) {
        descLbl.appendReadLess(after: textDescription, trailingContent: .readless)
    } else if sender.didTap(label: descLbl, inRange: readless) {
        descLbl.appendReadmore(after: textDescription, trailingContent: .readmore)
    } else { return }
    
    
    its not working for me , please alaborated in storyboard and other configuration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment