从 UILabel 获取截断的文本

发布于 2024-11-25 04:04:19 字数 275 浏览 2 评论 0原文

无论如何,我可以获得 UILabel 文本的截断版本吗?

简而言之,我有一段文本和两个 UILabels - 标签 A(2 行长)和标签 B(高度可变)。标签 A 位于标签 B 之上。其想法是,标签 A 显示文本段落的前两行,并且在某个用户操作后,标签 B 可见并显示文本的其余部分。

我无法确定标签 B 中应包含哪些内容,因为我不知道标签 A 中显示的内容。我还需要从标签 A 中删除“...”。

注意:我意识到这是一个有点令人费解,但有一些很好的理由,我不会用这些理由来混淆这个问题。

Is there anyway I can get the truncated version of the text for a UILabel?

In short, I have a paragraph of text, and two UILabels - label A, which is 2 lines long, and label B, which is a variable height. Label A is above label B. The idea is that label A shows the first two lines of the paragraph of text, and upon a certain user action, label B because visible and displays the rest of the text.

I'm having trouble determining what should go in label B, as I don't know what's being shown in label A. I'd need to also remove the "..." from label A.

Note: I realize this is a bit convoluted but there are some good reasons for it, which I won't clutter up the question with.

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

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

发布评论

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

评论(3

謸气贵蔟 2024-12-02 04:04:19

我想知道您是否可以使用 中的方法NSString UIKit Additions 来计算标签 A 的适合程度。

一种粗略的方法可能是从文本的第一个字符开始并测试它所占用的大小(-sizeWithFont:forWidth:lineBreakMode: 也许?)然后继续一次添加一个字符,直到它不再适合您的标签 A 为止。

我希望其他人能想出更好的方法来做到这一点,但上述应该可行。

更新

昨晚,我对自己的应用程序的 Core Text 进行了一些研究,发现了 CTFramesetterSuggestFrameSizeWithConstraints。您可以通过查看该函数中的 fitRange 来使用它来确定标签适合多少字符串。

更新 2:

我认为这应该可行,但我刚刚在此处输入了此内容,因此它甚至可能无法编译:

UIFont *uiFont = [UIFont systemFontOfZise:13.0f]; // whichever font you're using
CTFontRef ctFont = CTFontCreateWithName((CFStringRef)uiFont.fontName, uiFont.pointSize, NULL);
NSDictionary *attr = [NSDictionary dictionaryWithObject:(id)ctFont forKey:(id)kCTFontAttributeName];
CFRelease(ctfont);
NSAttributedString *attrString  = [[NSAttributedString alloc] initWithString:yourLabelText attributes:attr];
CTFrameSetterRef frameSetter = CTFrameSetterCreateWithAttributedString((CFAttributedStringRef)attrString);
[attrString release];
CFRange fitRange;
CTFrameSetterSuggestFrameSizeWithConstrains(
    frameSetter,
    CFRangeMake(0, 0),
    NULL,
    CGSizeMake(labelWidth, labelHeight),
    &fitRange);
CFRelease(frameSetter);
CFIndex numberOfCharactersThatFit = fitRange.length;

I wonder if you could use the methods in the NSString UIKit Additions to figure out how much fits into label A.

A crude way might be to start with the first character of your text and test for the size it would take up (-sizeWithFont:forWidth:lineBreakMode: maybe?) and then keep adding characters one at a time until it doesn't fit into your label A any more.

I hope somebody else can come up with a better way to do this, but the above should work.

Update

Last night I looked a bit into Core Text for my own app and came across CTFramesetterSuggestFrameSizeWithConstraints. You could maybe use this to figure out how much of your string fits into the label, by looking at the fitRange in that function.

Update 2:

I think this should work, but I have just typed this in here, so it may not even compile:

UIFont *uiFont = [UIFont systemFontOfZise:13.0f]; // whichever font you're using
CTFontRef ctFont = CTFontCreateWithName((CFStringRef)uiFont.fontName, uiFont.pointSize, NULL);
NSDictionary *attr = [NSDictionary dictionaryWithObject:(id)ctFont forKey:(id)kCTFontAttributeName];
CFRelease(ctfont);
NSAttributedString *attrString  = [[NSAttributedString alloc] initWithString:yourLabelText attributes:attr];
CTFrameSetterRef frameSetter = CTFrameSetterCreateWithAttributedString((CFAttributedStringRef)attrString);
[attrString release];
CFRange fitRange;
CTFrameSetterSuggestFrameSizeWithConstrains(
    frameSetter,
    CFRangeMake(0, 0),
    NULL,
    CGSizeMake(labelWidth, labelHeight),
    &fitRange);
CFRelease(frameSetter);
CFIndex numberOfCharactersThatFit = fitRange.length;
滥情哥ㄟ 2024-12-02 04:04:19

感谢托马斯·穆勒
请务必将 myLabel 的换行模式设置为:

myLabel.lineBreakMode = NSLineBreakByWordWrapping;

通过此方法,您可以获得实际适合约束大小的分块字符串。
这是烘焙的代码:

- (NSArray *)truncate:(NSString *)text
{
    NSMutableArray *textChunks = [[NSMutableArray alloc] init];

    NSString *chunk = [[NSString alloc] init];

    CTFramesetterRef frameSetter;
    UIFont *uiFont = [UIFont systemFontOfSize:17.0f];
    CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef)uiFont.fontName, uiFont.pointSize, NULL);
    NSDictionary *attr = [NSDictionary dictionaryWithObject:(__bridge id)ctFont forKey:(id)kCTFontAttributeName];
    NSMutableAttributedString *attrString  = [[NSMutableAttributedString alloc] initWithString:text attributes:attr];

    CFRange fitRange;
    while (attrString.length>0) {

        frameSetter = CTFramesetterCreateWithAttributedString ((__bridge CFAttributedStringRef) attrString);
            CTFramesetterSuggestFrameSizeWithConstraints(frameSetter, CFRangeMake(0,0), NULL, CGSizeMake(myLabel.frame.size.width, myLabel.frame.size.height), &fitRange);
        CFRelease(frameSetter);

       chunk = [[attrString attributedSubstringFromRange:NSMakeRange(0, fitRange.length)] string];

        [textChunks addObject:chunk];

        [attrString setAttributedString: [attrString attributedSubstringFromRange:NSMakeRange(fitRange.length, attrString.string.length-fitRange.length)]];

    }


    return textChunks;
}

thanks to Thomas Müller
be sure to set line break mode the myLabel to this:

myLabel.lineBreakMode = NSLineBreakByWordWrapping;

by this method you can get chunked strings that actually fit in the constrained size.
Here is the baked code:

- (NSArray *)truncate:(NSString *)text
{
    NSMutableArray *textChunks = [[NSMutableArray alloc] init];

    NSString *chunk = [[NSString alloc] init];

    CTFramesetterRef frameSetter;
    UIFont *uiFont = [UIFont systemFontOfSize:17.0f];
    CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef)uiFont.fontName, uiFont.pointSize, NULL);
    NSDictionary *attr = [NSDictionary dictionaryWithObject:(__bridge id)ctFont forKey:(id)kCTFontAttributeName];
    NSMutableAttributedString *attrString  = [[NSMutableAttributedString alloc] initWithString:text attributes:attr];

    CFRange fitRange;
    while (attrString.length>0) {

        frameSetter = CTFramesetterCreateWithAttributedString ((__bridge CFAttributedStringRef) attrString);
            CTFramesetterSuggestFrameSizeWithConstraints(frameSetter, CFRangeMake(0,0), NULL, CGSizeMake(myLabel.frame.size.width, myLabel.frame.size.height), &fitRange);
        CFRelease(frameSetter);

       chunk = [[attrString attributedSubstringFromRange:NSMakeRange(0, fitRange.length)] string];

        [textChunks addObject:chunk];

        [attrString setAttributedString: [attrString attributedSubstringFromRange:NSMakeRange(fitRange.length, attrString.string.length-fitRange.length)]];

    }


    return textChunks;
}
や莫失莫忘 2024-12-02 04:04:19

对于标签 A,对于您正在使用的特定字体,计算应完美适合两行的近似字符。

对于标签 B,设置整个文本必须适合的变量高度。

For Label A, calculate approximate character that should fit perfectly for two lines, for the particular font you are using.

For label B, set variable Height that the whole text must fit into it.

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