5

I'm loading some help text from a plist and displaying the same in the form of UILabels housed in a UIScrollView. Portion of the code follows:

    UILabel *sectionDetailLabel = [[[UILabel alloc] initWithFrame:CGRectMake(34, myOriginForThisSection, 286, 20)] autorelease];
    sectionDetailLabel.backgroundColor = [UIColor clearColor];
    sectionDetailLabel.numberOfLines = 0;
    sectionDetailLabel.font = [UIFont systemFontOfSize:12];
    sectionDetailLabel.textColor = [UIColor blackColor];
    sectionDetailLabel.textAlignment = UITextAlignmentLeft;
    sectionDetailLabel.lineBreakMode = UILineBreakModeWordWrap;

    [baseScrollView addSubview:sectionDetailLabel];

    [sectionDetailLabel setText:myStringForThisSection];
    [sectionDetailLabel sizeToFit];

While any 'long' text is getting wrapped into multiple lines correctly, I'm unable to manually insert any line-breaks using newline '\n' characters in 'myStringForThisSection'. I only see the characters '\' and 'n' printed in the UILabel wherever I wanted the line-break, instead.

I looked this up and the general consensus seemed to be that setting numberOfLines to 0, setting the lineBreakMode to a valid value and invoking sizeToFit (or setting the frame of the UILabel based on sizeWithFont:) should do. All of which I seem to be doing in the code above - and works perfectly when fitting long strings of unknown length into multiple lines on the UILabel. So what could be missing here?

Note: All the variables used - baseScrollView, myStringForThisSection and myOriginForThisSection - were loaded before the above code began executing, and work fine.

Dev Kanchen
  • 2,332
  • 3
  • 28
  • 40
  • If the string comes from an external source, this will happen. If it's declared/created in the code (maybe even possibly in a plist), the newline will be encoded as such. A newline must be followed by space, if that line is a blank line, though. – Henrik Erlandsson Nov 23 '10 at 10:08

3 Answers3

8

UILabel doesn't interpret the escape sequence \n. You can insert the real character that represents the Carriage Return and/or the Line Feed. Make a char to hold your newline and then insert it.

unichar newLine = '\n';
NSString *singleCR = [NSString stringWithCharacters:&newLine length:1];
[myStringForThisSection insertString:singleCR atIndex:somePlaceIWantACR];

As long as your myStringForThisSection is mutable, that should do it.

danimal
  • 516
  • 1
  • 8
  • 21
Scott Gustafson
  • 342
  • 2
  • 3
3

I had trouble with Scot Gustafson's answer above in XCode 4.3

Try this instead:

unichar chr[1] = {'\n'};
NSString *cR = [NSString stringWithCharacters:(const unichar *)chr length:1];

Then use in your code something like this:

self.myLabel.text = [NSString stringWithFormat:@"First Label Line%@Second Label Line", cR];
DoctorG
  • 1,168
  • 7
  • 11
  • It's...been a long time. I can see the merits of not using an "insertAtIndex" type instruction though, which could always be dangerous, and especially when you're dealing with data in several different languages. If someone else finds this particularly useful, or finds the previous code to be outdated as well, I could "promote" this answer or vote it up. – Dev Kanchen Mar 07 '12 at 19:54
  • Dev either way works, the way I do it just makes more sense to simple minds like mine! I did have trouble with your definition of singleCR -- I got an error in IOS5 xCode 4.3.1 – DoctorG Mar 12 '12 at 01:39
  • Hehe sure. I'll check out both solutions once I have time, and post back. – Dev Kanchen Mar 12 '12 at 08:36
2

I couldn't get Scott & DoctorG's solution to work (though I didn't spend too much time trying), but here's the simple solution that works for me when I'm extracting escaped text from an xml file.

Inside my string function class, I define:

+(NSString)escapeXml:(NSString*)string {
    return [string stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"];
}
Frank Yin
  • 1,920
  • 1
  • 17
  • 12