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

前端 未结 10 1630
孤街浪徒
孤街浪徒 2020-11-27 05:27

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 bu

10条回答
  •  無奈伤痛
    2020-11-27 05:40

    I have better way to find it.

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

    1.Add CoreText.framework.
    2.Import #import .
    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)
    

提交回复
热议问题