Get line break in UILabel due to Autolayout

I want to get the text with newlines as UILabel shows up with autoplay on the phone screen. Thank.

For example: if I assign

label.text = "dhasghdsgah dgahjdg ahjgd hkagkhdhk ajsh djkah"

      

When displayed on screen, it looks like this depending on the width of the screen:

dhasghdsgah dgahjdg ahjgd

 hkagkhdhk ajsh

  djkah

      

I want to know where '\ n' was inserted by autodetection.

Please correct me if I missed something.

Find the screenshot: There is no space in the label.

enter image description here

+3


source to share


2 answers


I solved this problem using this method:

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

    let text:NSString = label.text! as NSString
    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: CGFloat(0), y: CGFloat(0), width: CGFloat(rect.size.width), height: CGFloat(100000)), transform: .identity)

    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
}

      

This method returns an array of strings that are on different lines. Now you can use this array as per your need to create a new string with \ n join.



My use:

            var stringArray = [String]()

            for newItem in self.getLinesArrayOfStringInLabel(label: item.labelToAdd) {
                stringArray.append(newItem.replacingOccurrences(of: "\n", with: ""))
            }
            let stringToSend = stringArray.joined(separator: "\n")
            print(stringToSend)

      

Feel free to ask any detail. Thanks to

+2


source


Here's the code for detecting line breaks inside UILabel works

- (int)getLengthForString:(NSString *)str fromFrame:(CGRect)frame withFont:(UIFont *)font
{
    int length = 1;
    int lastSpace = 1;
    NSString *cutText = [str substringToIndex:length];
    CGSize textSize = [cutText sizeWithFont:font constrainedToSize:CGSizeMake(frame.size.width, frame.size.height + 500)];
    while (textSize.height <= frame.size.height)
    {
        NSRange range = NSMakeRange (length, 1);
        if ([[str substringWithRange:range] isEqualToString:@" "])
        {
            lastSpace = length;
        }
        length++;
        cutText = [str substringToIndex:length];
        textSize = [cutText sizeWithFont:font constrainedToSize:CGSizeMake(frame.size.width, frame.size.height + 500)];
    }
    return lastSpace;
}


-(NSString*) getLinebreaksWithString:(NSString*)labelText forWidth:(CGFloat)lblWidth forPoint:(CGPoint)point
{
    //Create Label
    UILabel *label = [[UILabel alloc] init];
    label.text = labelText;
    label.numberOfLines = 0;
    label.lineBreakMode = NSLineBreakByWordWrapping;

    //Set frame according to string
    CGSize size = [label.text sizeWithFont:label.font
                         constrainedToSize:CGSizeMake(lblWidth, MAXFLOAT)
                             lineBreakMode:UILineBreakModeWordWrap];
    [label setFrame:CGRectMake(point.x , point.y , size.width , size.height)];

    //Add Label in current view
    [self.view addSubview:label];

    //Count the total number of lines for the Label which has NSLineBreakByWordWrapping line break mode
    int numLines = (int)(label.frame.size.height/label.font.leading);

    //Getting and dumping lines from text set on the Label
    NSMutableArray *allLines = [[NSMutableArray alloc] init];

    BOOL shouldLoop = YES;
    while (shouldLoop)
    {
        //Getting length of the string from rect with font
        int length = [self getLengthForString:labelText fromFrame:CGRectMake(point.x, point.y, size.width, size.height/numLines) withFont:label.font] + 1;        

        [allLines addObject:[labelText substringToIndex:length]];

        labelText = [labelText substringFromIndex:length];
        if(labelText.length<length)
            shouldLoop = NO;
    }

    [allLines addObject:labelText];
    //NSLog(@"\n\n%@\n",allLines);

    return [allLines componentsJoinedByString:@"\n"];
}

      

How to use:



NSString *labelText = @"We are what our thoughts have made us; so take care about what you think. Words are secondary. Thoughts live; they travel far.";

NSString *stringWithLineBreakChar = [self getLinebreaksWithString:labelText forWidth:200 forPoint:CGPointMake(15, 15)];
NSLog(@"\n\n%@",stringWithLineBreakChar);

      

You just need to set the parameters required for getLinebreaksWithString and you will get a line with each "\ n" included. Use the label width and starting point that you created in the storyboard.

Link: fooobar.com/questions/684351 / ...

0


source







All Articles