Objective-c Line breaks every 10 characters (Keepi

2020-06-06 02:59发布

问题:

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!

回答1:

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];
}


回答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--;
}


回答3:

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



回答4:

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);