How to Get Text/String from Nth Line of Uilabel

How to get text / String from nth line of UILabel?

I don't think there's a native way for doing this (like a "takethenline" method).

I can figure out a tricky solution but I'm not sure is the best one.

You could split your label into an array of words.

Then you could loop the array and check the text height until that word like this:

NSString *texttocheck;
float old_height = 0;
int linenumber = 0;

for (x=0; x<[wordarray lenght]; x++) {
texttocheck = [NSString stringWithFormat:@"%@ %@", texttocheck, [wordarray objectAtIndex:x]];

float height = [text sizeWithFont:textLabel.font
constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999)
lineBreakMode:UILineBreakModeWordWrap].height;

if (old_height < height) {
linenumber++;
}
}

If height changes, it means there's a line break before the word.

I can't check if the syntax is written correctly now, so you have to check it yourself.

Get string of first line in a UILabel

1.Add CoreText.framework. 2. Import #import CoreText/CoreText.h>.
Then use below method -

-(NSArray *)getLinesArrayOfStringInLabel:(UILabel *)label
{
NSString *text = [label text];
UIFont *font = [label font];
CGRect rect = [label frame];

CTFontRef myFont = CTFontCreateWithName(( CFStringRef)([font fontName]), [font pointSize], NULL);
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text];
[attStr addAttribute:(NSString *)kCTFontAttributeName value:( id)myFont range:NSMakeRange(0, attStr.length)];

CFRelease(myFont);

CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString(( CFAttributedStringRef)attStr);

CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0,0,rect.size.width,100000));

CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL);

NSArray *lines = ( NSArray *)CTFrameGetLines(frame);

NSMutableArray *linesArray = [[NSMutableArray alloc]init];

for (id line in lines)
{
CTLineRef lineRef = ( CTLineRef )line;
CFRange lineRange = CTLineGetStringRange(lineRef);
NSRange range = NSMakeRange(lineRange.location, lineRange.length);

NSString *lineString = [text substringWithRange:range];

CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithFloat:0.0]));
CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithInt:0.0]));

//NSLog(@"''''''''''''''''''%@",lineString);
[linesArray addObject:lineString];

}
[attStr release];

CGPathRelease(path);
CFRelease( frame );
CFRelease(frameSetter);


return (NSArray *)linesArray;
}

I found this answer from below url - How to get text from nth line of UILabel?

NSString *firstLineString = [[self getLinesArrayOfStringInLabel:yourLabel] objectAtIndex:0];

iOS Get first attributed line in UILabel

Swift 3

 let arrayLines = getLinesArrayFromLabel(label: lbl)
print(arrayLines[0])

func getLinesArrayFromLabel(label:UILabel) -> [String] {

let text:NSString = label.text! as NSString // TODO: Make safe?
let font:UIFont = label.font
let rect:CGRect = label.frame

let myFont:CTFont = CTFontCreateWithName(font.fontName as CFString, font.pointSize, nil)
let attStr:NSMutableAttributedString = NSMutableAttributedString(string: text as String)
attStr.addAttribute(String(kCTFontAttributeName), value:myFont, range: NSMakeRange(0, attStr.length))
let frameSetter:CTFramesetter = CTFramesetterCreateWithAttributedString(attStr as CFAttributedString)
let path:CGMutablePath = CGMutablePath()
path.addRect(CGRect(x:0, y:0, width:rect.size.width, height:100000))

let frame:CTFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil)
let lines = CTFrameGetLines(frame) as NSArray
var linesArray = [String]()

for line in lines {
let lineRange = CTLineGetStringRange(line as! CTLine)
let range:NSRange = NSMakeRange(lineRange.location, lineRange.length)
let lineString = text.substring(with: range)
linesArray.append(lineString as String)
}
return linesArray
}

NSAttributedString

func getLinesArrayOfStringInLabel(label:UILabel) -> [NSAttributedString] {

let text:NSAttributedString = label.attributedText! // TODO: Make safe?
let font:UIFont = label.font
let rect:CGRect = label.frame

let myFont:CTFont = CTFontCreateWithName(font.fontName as CFString, font.pointSize, nil)
let attStr:NSMutableAttributedString = NSMutableAttributedString(attributedString: text)
attStr.addAttribute(String(kCTFontAttributeName), value:myFont, range: NSMakeRange(0, attStr.length))
let frameSetter:CTFramesetter = CTFramesetterCreateWithAttributedString(attStr as CFAttributedString)
let path:CGMutablePath = CGMutablePath()
path.addRect(CGRect(x:0, y:0, width:rect.size.width, height:100000))

let frame:CTFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil)
let lines = CTFrameGetLines(frame) as NSArray
var linesArray = [NSAttributedString]()

for line in lines {
let lineRange = CTLineGetStringRange(line as! CTLine)
let range:NSRange = NSMakeRange(lineRange.location, lineRange.length)
let lineString = text.attributedSubstring(from: range)
linesArray.append(lineString)
}
return linesArray
}

Multiple lines of text in UILabel

Set the line break mode to word-wrapping and the number of lines to 0:

// Swift
textLabel.lineBreakMode = .byWordWrapping
textLabel.numberOfLines = 0

// Objective-C
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.numberOfLines = 0;

// C# (Xamarin.iOS)
textLabel.LineBreakMode = UILineBreakMode.WordWrap;
textLabel.Lines = 0;

Restored old answer (for reference and devs willing to support iOS below 6.0):

textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.numberOfLines = 0;

On the side: both enum values yield to 0 anyway.

How to find and replace UILabel's value on a specific line?

Assuming from your screen shot that each line is separated by a newline character you can split the text based on that.

Here is an example in Swift 3:

if let components = label.text?.components(separatedBy: "\n"), components.count > 1 {
let secondLine = components[2]
let editedSecondLine = secondLine + "edited"
label.text = label.text?.replacingOccurrences(of: secondLine, with: editedSecondLine)
}

You should make sure there is a value at whatever index your interested in. This example makes sure that there are more than a single component before retrieving the value.

You can then replace the second line with your edited line.

Hope that helps.

Is there are way to determine text end coordinates in UILabel? (not label frame rect)

I have found something for you. please refer this answer. it may help you.

this answer has an algorithm that returns the length of NSString that can fit into the UILabel. and using that you can find the text of the first line.

After that, you can easily find the actual size of the second line based on the remaining text.



Related Topics



Leave a reply



Submit