I want to get first two lines text from UIlabel.I have searched a lot but not find any solution.Please tell me how to get first two lines text.
Asked
Active
Viewed 720 times
-5
-
please add your sample text and what you are using. – Yatendra Feb 16 '18 at 09:24
-
Like the example in one paragraph set text in UILabel.Then I want to get first two lines from the paragraph. – Gaurav Gupta Feb 16 '18 at 09:27
-
1Can I ask why would you would need to do this? you are basically cutting a string based on the size of a UI element that will be different sizes on different devices. what are you trying to achieve? – Scriptable Feb 16 '18 at 09:28
-
I am basically trying to append "View more..." text in UIlabel when text is greater than 2 lines.So please tell me how to achieve this. – Gaurav Gupta Feb 16 '18 at 09:30
3 Answers
1
Use this extension check if your label's number of line granter then 2 or whatever you target then apply this:
extension UILabel {
func addTrailing(with trailingText: String, moreText: String, moreTextFont: UIFont, moreTextColor: UIColor) {
let readMoreText: String = trailingText + moreText
let lengthForVisibleString: Int = self.vissibleTextLength()
let mutableString: String = self.text!
let trimmedString: String? = (mutableString as NSString).replacingCharacters(in: NSRange(location: lengthForVisibleString, length: ((self.text?.characters.count)! - lengthForVisibleString)), with: "")
let readMoreLength: Int = (readMoreText.characters.count)
let trimmedForReadMore: String = (trimmedString! as NSString).replacingCharacters(in: NSRange(location: ((trimmedString?.characters.count ?? 0) - readMoreLength), length: readMoreLength), with: "") + trailingText
let answerAttributed = NSMutableAttributedString(string: trimmedForReadMore, attributes: [NSFontAttributeName: self.font])
let readMoreAttributed = NSMutableAttributedString(string: moreText, attributes: [NSFontAttributeName: moreTextFont, NSForegroundColorAttributeName: moreTextColor])
answerAttributed.append(readMoreAttributed)
self.attributedText = answerAttributed
}
func vissibleTextLength() -> Int {
let font: UIFont = self.font
let mode: NSLineBreakMode = self.lineBreakMode
let labelWidth: CGFloat = self.frame.size.width
let labelHeight: CGFloat = self.frame.size.height
let sizeConstraint = CGSize(width: labelWidth, height: CGFloat.greatestFiniteMagnitude)
let attributes: [AnyHashable: Any] = [NSFontAttributeName: font]
let attributedText = NSAttributedString(string: self.text!, attributes: attributes as? [String : Any])
let boundingRect: CGRect = attributedText.boundingRect(with: sizeConstraint, options: .usesLineFragmentOrigin, context: nil)
if boundingRect.size.height > labelHeight {
var index: Int = 0
var prev: Int = 0
let characterSet = CharacterSet.whitespacesAndNewlines
repeat {
prev = index
if mode == NSLineBreakMode.byCharWrapping {
index += 1
} else {
index = (self.text! as NSString).rangeOfCharacter(from: characterSet, options: [], range: NSRange(location: index + 1, length: self.text!.characters.count - index - 1)).location
}
} while index != NSNotFound && index < self.text!.characters.count && (self.text! as NSString).substring(to: index).boundingRect(with: sizeConstraint, options: .usesLineFragmentOrigin, attributes: attributes as? [String : Any], context: nil).size.height <= labelHeight
return prev
}
return self.text!.characters.count
}
}
Count Label's number of line:
func countLabelLines(label: UILabel) -> Int {
// Call self.layoutIfNeeded() if your view uses auto layout
self.view.layoutIfNeeded()
let myText = label.text! as NSString
let rect = CGSize(width: label.bounds.width, height: CGFloat.greatestFiniteMagnitude)
let labelSize = myText.boundingRect(with: rect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: label.font], context: nil)
return Int(ceil(CGFloat(labelSize.height) / label.font.lineHeight))
}
Example:
if self.countLabelLines(label: lblmedicationDetailText) >= numberOflines{
let readmoreFont = UIFont(name: "Montserrat-Regular", size: 15.0)
let readmoreFontColor = UIColor.init(red: 1.0/255.0, green: 100.0/255.0, blue: 157.0/255.0, alpha: 1.0)
DispatchQueue.main.async {
self.lblmedicationDetailText.addTrailing(with: "... ", moreText: "Read More", moreTextFont: readmoreFont!, moreTextColor: readmoreFontColor)
}
}

Som Parkash
- 234
- 3
- 9
-
1That looks like a verbatim copy from https://stackoverflow.com/a/44064496. Have a look at https://stackoverflow.com/help/referencing about how to reference code written by others, and plagiarism. – Martin R Feb 16 '18 at 09:52
-
__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds. error occur when the string is long without space. – Gaurav Gupta Feb 16 '18 at 10:31
0
let numOfLine = self.numberOfLinesInLabel(self.testingLabel.text!, labelWidth: self.testingLabel.frame.width, labelHeight: self.testingLabel.frame.height, font: self.testingLabel.font)
self.getNumberOfLineDict.setValue(numOfLine, forKey: String(i))
let Lines : Int = getNumberOfLineDict.valueForKey(String(indexPath.row)) as! Int // I did it in tableview. So I used indexPath.row
if Lines > 2
{
ReadmoreBtn.isHidden = false
}
else
{
ReadmoreBtn.isHidden = true
}
To get the number of lines in a text
func numberOfLinesInLabel(yourString: String, labelWidth: CGFloat, labelHeight: CGFloat, font: UIFont) -> Int {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.minimumLineHeight = labelHeight
paragraphStyle.maximumLineHeight = labelHeight
paragraphStyle.lineBreakMode = .ByWordWrapping
let attributes: [String: AnyObject] = [NSFontAttributeName: font, NSParagraphStyleAttributeName: paragraphStyle]
let constrain = CGSizeMake(labelWidth, CGFloat(Float.infinity))
let size = yourString.sizeWithAttributes(attributes)
let stringWidth = size.width
let numberOfLines = ceil(Double(stringWidth/constrain.width))
return Int(numberOfLines)
}

Catherine
- 654
- 5
- 15
-
-
ok. Using my code u can do whatever u want when the line's count is greater than 2 – Catherine Feb 16 '18 at 10:49
0
My advice is doing something on UI only.
You can set a UIView(such as it has gradual clear to white view and has a label "View more...") to cover the original label except first two lines.
You can get the first two lines height by label.font.lineHeight * 2
.

ribilynn
- 460
- 5
- 21