3

If I have a string that I am going to load into a TextField how can I make a line break \n occur every 10 characters (including spaces and whatnot) but not go to the next line mid-word... Like wrap the text with a max of 10 characters? But I'm not just wrapping in a UITextField I actually need the \n's entered because it will be used in something else as well... (This is for iOS if that matters) any help is appreciated I'm really stuck!

Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195

4 Answers4

5

You might want to make use of NSScanner in a loop to put together this kind of thing, but to figure out the precise algorithm you'd need to clarify exactly how you want it to work. Here are questions that you would need to answer:

  1. Should sequence of more than one whitespace between words be "collapsed" into a single whitespace for the purpose of wrapping text, or should a sequence of 5 consecutive whitespaces be counted as 5 characters against your 10 character per line? I will assume you want multiple spaces to be collapsed rather than preserved
  2. How do you want it to work if you have a single word that is greater than 10 characters? Do you want it to end up with a line that is greater than 10 characters, or would you prefer the newline to be inserted and force a mid-word line break in that situation? I will assume you want to allow words longer than 10 characters to expand beyond the 10 character limit.

With these assumptions about your problem in mind, I would code it like this:

NSMutableString *resultString = [[NSMutableString alloc] init];
NSMutableString *currentLine = [[NSMutableString alloc] init];
NSScanner *scanner = [NSScanner scannerWithString:sourceString];
NSString *scannedString = nil;
while ([scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString: &scannedString]) {
    if ([currentLine length] + [scannedString length] <= 10) {
        [currentLine appendFormat:@"%@ ", scannedString];
    }
    else if ([currentLine length] == 0) { // Newline but next word > 10
        [resultString appendFormat:@"%@\n", scannedString];
    }
    else { // Need to break line and start new one
        [resultString appendFormat:@"%@\n", currentLine];
        [currentLine setString:[NSString stringWithFormat:@"%@ ", scannedString]];
    }
    [scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL];
}
Tim Dean
  • 8,253
  • 2
  • 32
  • 59
2

I created something that actually does the breaks, not at every 10 chars, but between words, not there is no hyphenation engine there, that would require a dictionary. I built it off of Perceptions answer.

NSMutableString * guid = [NSMutableString stringWithString: @"Some suitably long string will be used for demonstration purposes"];
int lastSpace=0;
int lastbreak=0;
NSUInteger i = [guid length];
while(i > 0) {
    if ([guid characterAtIndex:i-1]==' ')
        lastSpace=i;
    lastbreak++;
    if (lastbreak>9) {
        if (lastSpace!=0) {
            [guid insertString:@"\n" atIndex: lastSpace];
        } else {
            // we have not found a space in 10 chars, so break where there is no space.
            // no H&J engine here, so we can add the - or not.
            [guid insertString:@"-\n" atIndex: i];
            i++;  // since were adding a character, dont skip a character.
        }
        lastbreak=0;
        lastSpace=0;
    }
    i--;
}
nycynik
  • 7,371
  • 8
  • 62
  • 87
  • Very easy to follow! The lastSpace variable! Why didn't I think of that ;) Thankyou!! – Albert Renshaw Feb 29 '12 at 00:05
  • Wait sorry this doesn't work like I thought it did, it will allow more than 10 characters on a line. I need 10 as a max. It needs to line break more often – Albert Renshaw Feb 29 '12 at 00:07
  • With some tweaking I got it working (counting the "i" variable from the start and forcing the breaks at spaces when it goes over 10 instead of after the next word when it goes over to) Thanks! – Albert Renshaw Feb 29 '12 at 00:18
  • Ahh! No I got some with 11 /: Maybe it isn't counting spaces but by the looks of your code it does! hmmm – Albert Renshaw Feb 29 '12 at 00:21
  • if you add the - to the line, it has to count that, sorry I did not have code for that. I would add there an i++ – nycynik Feb 29 '12 at 17:06
1

I'd do it in a way something like that:

NSString *finalString = @"";
NSString *yourString = @"This is your very very long string with many words and letters and spaces, haha";
NSArray *someArray = [yourString componentsSeparatedByString:@" "]; //that will make an array with strings separated by spaces
for (int i = 0; i < [someArray count]; i++) {
  NSArray *someArray2 = [finalString componentsSeparatedByString:@"\n"];
  if ([[someArray objectAtIndex:i]length] + [[someArray2 lastObject]length] > 9 )
    finalString = [NSString stringWithFormat:@"%@\n%@", finalString, [someArray objectAtIndex:i]];
  else
    finalString = [NSString stringWithFormat:@"%@ %@", finalString, [someArray objectAtIndex:i]];
}

I believe that something like that should work. I don't have a Mac nearby, so I wrote that down by my memory(which isn't always flawless). So there might be a few errors in the code.

Hope it helps

nycynik
  • 7,371
  • 8
  • 62
  • 87
Novarg
  • 7,390
  • 3
  • 38
  • 74
0

You will have to insert the newline characters into your string yourself, there isn't a built-in function for this afaik.

NSMutableString * guid = [NSMutableString stringWithString: @"Some suitably long string will be used for demonstration purposes"];
for(NSUInteger i = 10; i < [guid length] ; i += 10) {
    [guid insertString:@"\n" atIndex: i];
}

NSLog(@"GUID: %@", guid);
Perception
  • 79,279
  • 19
  • 185
  • 195