How to know the length of NSString that fits a UILabel with fixed size?

谁说胖子不能爱 提交于 2019-12-18 12:32:45

问题


I know NSString has methods that determine the frame size for it, using NSString UIKit Additions, sizeWithFont......

How about the other way around? I mean if I have a fixed frame size, how do I know how many characters or words for a NSString that can fit into it?

If I know this, I can cut off the NSString easily.

thanks


回答1:


It might not be the most elegant solution, but you could do something like this:

- (NSString *)string:(NSString *)sourceString reducedToWidth:(CGFloat)width withFont:(UIFont *)font {

    if ([sourceString sizeWithFont:font].width <= width)
        return sourceString;

    NSMutableString *string = [NSMutableString string];

    for (NSInteger i = 0; i < [sourceString length]; i++) {

        [string appendString:[sourceString substringWithRange:NSMakeRange(i, 1)]];

        if ([string sizeWithFont:font].width > width) {

            if ([string length] == 1)
                return nil;

            [string deleteCharactersInRange:NSMakeRange(i, 1)];

            break;
        }
    }

    return string;
}

Then call it like this:

NSString *test = @"Hello, World!";
CGFloat width = 40.0;
UIFont *font = [UIFont systemFontOfSize:[UIFont labelFontSize]];

NSString *reducedString = [self string:test reducedToWidth:width withFont:font];

NSLog(@"%@", reducedString);



回答2:


You cannot know/determine the number of characters that fits in a UILabel with fixed width because some characters are smaler than others, eg l and m.

There are two options:

  1. Use Mono-Space-Fonts (each character has also a fixed width). Then determine the width for one char in your font with your font-size and calculate the number of chars
  2. Allow any number of characters and check on insert if the inserted characters fit.

You have to know what behaviour you want to have. What should happen if there is text that does not fit. If you only want to truncate (like the solution of mortenfast does) then just use UILineBreakModeTailTruncation for the lineBreakMode-property of your UILabel (there are more options, like TruncateHead, Clip, Word Wrap)




回答3:


Thanks @Morten. I've updated the sample code to handle word separation. It also eliminates extra spaces in between words. It has not been tested in the field, but my tests have, thus far, proven OK. Please update at your leisure if you find improvements or bug/glitch fixes.

-(NSString*)string:(NSString*)sourceString reducedToWidth:(CGFloat)width withFont:(UIFont*)font {

    // if full string is within bounds, simply return the full string
    if( [sourceString sizeWithFont:font].width <= width ) return sourceString;

    // break up string into words. if <= 1 word, return original string
    NSArray* words = [sourceString componentsSeparatedByString:@" "];
    NSInteger numWords = [words count];
    if( numWords <= 1 ) return sourceString;

    // our return var. we populate as we go
    NSMutableString* str = [NSMutableString string];
    // temp var to test with before adding to return string
    NSMutableString* strTemp = [NSMutableString string];
    // string to hold word LESS spaces
    NSString* strWordTemp = nil;
    // the word we're currently on
    NSInteger numWord = 0;
    // whether we need to add a space (when not last word)
    Boolean addSpace = NO;

    // loop through our words....
    for( NSString* strWord in words ) {

        // which word we're on
        numWord++;

        // eliminate white space
        strWordTemp = [strWord stringByReplacingOccurrencesOfString:@" " withString:@""];

        // if this word is empty or was a space(s), skip it
        if( [strWordTemp isEqualToString:@""] ) continue;

        // append to temp string
        [strTemp appendString:strWordTemp];

        // if we're still within the bounds...
        if( [strTemp sizeWithFont:font].width <= width ) {

            // default = no extra space
            addSpace = NO;

            // if we're not the last word, add a space & check for length
            if( numWord < numWords ) {

                [strTemp appendString:@" "];

                // if adding space made it too long, then just don't add it!
                if( [strTemp sizeWithFont:font].width > width ) {

                    // it was too long with space, so we'll just add word
                    [str appendString:strWordTemp];
                    break;
                }
                // otherwise, it's OK to add the space
                else addSpace = YES;
            }

            // append to return string and continue
            [str appendFormat:@"%@%@", strWordTemp, ( addSpace ? @" " : @"" )];
        }
        // otherwise, we're done
        else break;
    }

    // return our result
    return str;
}



回答4:


Or you just just use the lineBreak property and set it to NSLineBreakByCharWrapping and move on with your life. https://stackoverflow.com/a/29088337/951349



来源:https://stackoverflow.com/questions/6422742/how-to-know-the-length-of-nsstring-that-fits-a-uilabel-with-fixed-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!