NSString 的前两行给出了宽度和字体

发布于 2024-12-20 16:05:14 字数 196 浏览 1 评论 0原文

我有一个很长的 NSStringUIFont 和所需的宽度。我只想获取适合给定 UIFont 宽度的字符串的前两行。我所说的“获取”是指获取一个子字符串。第二行可能会被截断,并且必须考虑到第一行的自动换行。

我怎样才能实现这个目标?请告诉我正确的方向。谢谢!

I've got a long NSString, UIFont and desired width. I'd like to get only two first lines of the string that fits the width with given UIFont. By "get" I mean getting a substring. The second line may be truncated and there must be a word wrap into the first line taken into consideration.

How can I achieve this? Please show me the right direction. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

長街聽風 2024-12-27 16:05:15

我认为没有一种简单、干净、优雅的方法可以做到这一点。但是,如果您查看 NSString UIKit Additions 参考,有一些方法可能有助于获得良好的近似值。

特别是,请查看:

 CGSize aSize = 
 [ myString  sizeWithFont:(UIFont *)aFont 
        constrainedToSize:(CGSize ) aSize ];

使用 aSize 指定所需的宽度,使用 2*fontSize(适用于 2 行)指定所需的高度。
将所得宽度 (aSize.width) 除以字体大小。如果字符串适合此框,这应该近似于被截断的位置。

现在不幸的是,您需要字体比例(磅值与宽度之比),我不知道如何获得。我根据经验确定它在 4 到 6 之间,但这就像说 pi 约为 3。

无论如何,字符串被截断的近似索引将是

 ( fontRatio * aSize.width ) / fontSize;

我编写了一个小型模拟器项目来测试线宽的各种组合、字体比例、字体大小等,欢迎您使用。它在这里:字符串测试项目

I don't think there is a simple, clean elegant way to do this. But if you look at the NSString UIKit Additions reference, there are methods that might help get a good approximation.

In particular, look at:

 CGSize aSize = 
 [ myString  sizeWithFont:(UIFont *)aFont 
        constrainedToSize:(CGSize ) aSize ];

Use aSize with your desired width and 2*fontSize (for 2 lines) for your desired height.
Take the resulting width (aSize.width) and divide by your font size. This should approximate where your string would get truncated if it were to fit in this box.

Now unfortunately, you need to font ratio (point size to width ratio), which I don't know how to get. I've determined empiracly that it's between 4 and 6, but that's like saying pi is about 3.

At any rate, the approximate index where your string gets truncated will be

 ( fontRatio * aSize.width ) / fontSize;

I wrote a small simulator project to test out the various combinations of line width, font ratio, font size, etc, which you're welcome to. It's here: string test project

简单气质女生网名 2024-12-27 16:05:15

这个怎么样?

- (NSString*) stringWithString:(NSString*)longString width:(float)width font:(UIFont*)font {

    if([longString sizeWithFont:font].width < width) {
        return longString;
    }

    NSMutableString* mutString = [NSMutableString stringWithFormat:@""];
    int i = 0;
    while ([mutString sizeWithFont:font].width < width && i < [longString length]) {
        unichar ch = [longString characterAtIndex:i];
        [mutString appendString:[NSString stringWithCharacters:&ch length:1]];
        i++;
    }

    NSString* shortenedString = [mutString substringToIndex:[mutString length] - 1];

    return shortenedString;
}

基本上我一一添加字符,并每次检查是否达到所需的宽度。

编辑:

使用自动换行和两行,您可以调整上面的代码并使用以下命令来检查大小:

[mutString sizeWithFont:font constrainedToSize:CGSizeMake(9999999, font.lineHeight*2) lineBreakMode:UILineBreakModeWordWrap]

您也可以对单词执行相同的操作,而不是单个字符:

[longString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]

这将返回一个数组,其中包含字符串中的所有单词您可以使用循环。

How about this?

- (NSString*) stringWithString:(NSString*)longString width:(float)width font:(UIFont*)font {

    if([longString sizeWithFont:font].width < width) {
        return longString;
    }

    NSMutableString* mutString = [NSMutableString stringWithFormat:@""];
    int i = 0;
    while ([mutString sizeWithFont:font].width < width && i < [longString length]) {
        unichar ch = [longString characterAtIndex:i];
        [mutString appendString:[NSString stringWithCharacters:&ch length:1]];
        i++;
    }

    NSString* shortenedString = [mutString substringToIndex:[mutString length] - 1];

    return shortenedString;
}

Basically I add the characters one by one and check everytime if the desired width is reached or not.

Edit:

With word wrapping and two lines you can adapt the code from above and use the following to check the size:

[mutString sizeWithFont:font constrainedToSize:CGSizeMake(9999999, font.lineHeight*2) lineBreakMode:UILineBreakModeWordWrap]

Instead of individual characters you can also do the same with words:

[longString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]

This returns an array that contains all the words in the string which you can use to loop through.

路弥 2024-12-27 16:05:15

“获取”是指绘制它,在前两行之后截断吗?或者检索一个字符串来表示前两行的空间适合什么?

对于前者,你可以直接绘制它,UILabel 会为你截断。

对于后者,我认为你必须自己进行分词并测量子字符串以找出合适的内容。

By "get" do you mean draw it, truncating after the first 2 lines? Or retrieve a string that represents what fits into the space for those first 2 lines?

For the former, you can just draw it, and the UILabel will truncate for you.

For the latter, I think you're going to have to do the word breaking yourself and measure the substrings to figure out what fits.

拥有 2024-12-27 16:05:15

您可以尝试将前两行文本放在必要宽度的 UILabel 中。您可以设置此标签的字体。
然后你可以有另一个标签,用不同的字体保存文本的剩余部分。
希望这有帮助。

You can try having the first two lines of text in a UILabel of the necessary width. you can set the font for the this label.
Then you can have another label which holds the remaining portion of the text with a different font.
Hope this helps.

心凉 2024-12-27 16:05:15
const int kPadding = 4; // Padding for the diference between the font's height and the line height - it's 2 for front and 2 for bottom

float maxHeight = (FONT_SIZE+kPadding)*kNumberOfLinesYouNeed;
CGSize labelSize = [yourString sizeWithFont:yourFont constrainedToSize:CGSizeMake(kYourNeededWidth, maxHeight) lineBreakMode:UILineBreakModeWordWrap];
youLabel.frame=CGRectMake(yourX, yourY, kYourNeededWidth, maxHeight);

对于任何错误,我深表歉意。我已经在脑子里写下了这个表格。

const int kPadding = 4; // Padding for the diference between the font's height and the line height - it's 2 for front and 2 for bottom

float maxHeight = (FONT_SIZE+kPadding)*kNumberOfLinesYouNeed;
CGSize labelSize = [yourString sizeWithFont:yourFont constrainedToSize:CGSizeMake(kYourNeededWidth, maxHeight) lineBreakMode:UILineBreakModeWordWrap];
youLabel.frame=CGRectMake(yourX, yourY, kYourNeededWidth, maxHeight);

I'm sorry for any mistakes. I have written this form my head.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文