Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Is there an easy way to get (or simply display) the text from a given line in a UILabel?

My UILabel is correctly displaying my text and laying it out beautifully but occasionally I need to be able to just show certain lines but obviously I need to know how UILabel has positioned everything to do this.

I know this could easily be done with a substring but I'd need to know the start and end point of the line.

Alternatively I could scroll the UILabel if there was some kind of offset to the UILabel's frame and hide the rest of the content I didn't want to see.

I've not been able to uncover anything that shows how this could be done easily. Anyone got any good ideas?

Thanks

iphaaw

like image 911
iphaaw Avatar asked Dec 12 '10 10:12

iphaaw


People also ask

How do you add a line break in UILabel?

To add line breaks in the text we'll use \n character in the string we want to assign to the label.

How do you make UILabel bold?

Double Click on Bold to select it, and then right click on it to see more options. Select font > Bold from that option. It should do the task.

What is UILabel?

A view that displays one or more lines of informational text.


1 Answers

I have better way to find it.

You can get this with the help of CoreText.framework.

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((__bridge CFStringRef)([font fontName]), [font pointSize], NULL);
    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text];
    [attStr addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)myFont range:NSMakeRange(0, attStr.length)];
    
    
    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge 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 = (__bridge NSArray *)CTFrameGetLines(frame);
    NSMutableArray *linesArray = [[NSMutableArray alloc]init];
    
    for (id line in lines)
    {
        CTLineRef lineRef = (__bridge CTLineRef )line;
        CFRange lineRange = CTLineGetStringRange(lineRef);
        NSRange range = NSMakeRange(lineRange.location, lineRange.length);
        
        NSString *lineString = [text substringWithRange:range];
        [linesArray addObject:lineString];
    }

    return (NSArray *)linesArray;
}

Call this method :-

NSArray *linesArray = [self getLinesArrayOfStringInLabel:yourLabel];

Now you can use linesArray.

SWIFT 4 VERSION

func getLinesArrayOfString(in label: UILabel) -> [String] {
        
        /// An empty string's array
        var linesArray = [String]()
        
        guard let text = label.text, let font = label.font else {return linesArray}
        
        let rect = label.frame
        
        let myFont = CTFontCreateWithFontDescriptor(font.fontDescriptor, 0, nil)
        let attStr = NSMutableAttributedString(string: text)
        attStr.addAttribute(kCTFontAttributeName as NSAttributedString.Key, value: myFont, range: NSRange(location: 0, length: 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), transform: .identity)
        
        let frame: CTFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil)
        guard let lines = CTFrameGetLines(frame) as? [Any] else {return linesArray}
        
        for line in lines {
            let lineRef = line as! CTLine
            let lineRange: CFRange = CTLineGetStringRange(lineRef)
            let range = NSRange(location: lineRange.location, length: lineRange.length)
            let lineString: String = (text as NSString).substring(with: range)
            linesArray.append(lineString)
        }
        return linesArray
 }

Use:

let lines: [String] = getLinesArrayOfString(in: label)
like image 145
TheTiger Avatar answered Sep 29 '22 09:09

TheTiger