在 NSStringDrawingTruncatesLastVisibleLine 中使用省略号 (...) 以外的其他内容
Use something else than ellipsis (...) with NSStringDrawingTruncatesLastVisibleLine
我正在尝试使用 [NSAttributedString drawWithRect:options:context:]
方法在后台呈现一些文本,并且我正在传递 (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading| NSStringDrawingTruncatesLastVisibleLine | NSLineBreakByWordWrapping)
作为选项。如果我的字符串长于两行(我已经为此计算了矩形的最大高度),我的文本将被截断 ...
.
效果很好,但是,我需要使用 ...more
进行截断(最后使用 "more"),而不是 ...
。
所有渲染都必须在后台线程上完成,因此任何 UI 组件都是不可能的。并且请不要推荐 TTTAttributedLabel
,因为我一开始就试图摆脱它,因为它导致我的应用程序滚动性能很差(已经尝试过了)。
在后台线程中绘制字符串时如何使用自定义截断标记?
可能不是最有效的方法,但我最终是这样的:
检查具有所需宽度且没有高度限制的字符串的大小(在 draw 方法中使用 MAXFLOAT
作为边界矩形的高度):
NSStringDrawingOptions drawingOptions = (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading);
[stringToDraw boundingRectWithSize:maximumSize options:drawingOptions context:nil].size;
我知道字体大小,检查结果大小的高度并检查它是否高于预定高度,这表明它是否超过两行。
如果超过两行,使用 [=17] 处答案的修改版本,获取 ...more
大致开始的矩形点处的字符索引=](该点在原文矩形第二行右下角附近某处):
//this string spans more than two lines.
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
// init text container
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:size];
textContainer.lineFragmentPadding = 0;
textContainer.maximumNumberOfLines = 2;
textContainer.lineBreakMode = NSLineBreakByClipping;
[layoutManager addTextContainer:textContainer];
CGPoint moreStartLocation = CGPointMake(size.width - 60, 30); //35 magic number
NSUInteger characterIndex = [layoutManager characterIndexForPoint:moreStartLocation
inTextContainer:textContainer
fractionOfDistanceBetweenInsertionPoints:NULL];
stringToDraw = [attributedString attributedSubstringFromRange:NSMakeRange(0, characterIndex)].mutableCopy;
[stringToDraw appendAttributedString:self.truncationText];
size = CGSizeMake(size.width, 35);
将原字符串截断为那里的字符(可选:也可以从limit中找到最后一个白色space(例如space,换行符)字符并得到子串从那时起避免剪字)。将“...更多”添加到原始字符串。 (文本可以是任何东西,具有任何属性。只要确保它能在两行中适合结果矩形。我已将其固定为 60px,但也可以获取所需截断字符串的大小,并使用其宽度精确找到最后一个字符)
照常渲染新字符串(以“...more”结尾):
UIGraphicsBeginImageContextWithOptions(contextSize, YES, 0);
[stringToDraw drawWithRect:rectForDrawing options:drawingOptions context:nil];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
这个方法的好处是,因为我们没有接触 UIKit(UIGraphics...
函数和 UIImage
是 thread-safe)我们可以执行整个过程在后台 thread/queue。我正在使用它在背景中预渲染一些带有 attributes/links 等的文本内容,否则在滚动时会在 UI 线程中占用一两帧,并且效果很好。
我正在尝试使用 [NSAttributedString drawWithRect:options:context:]
方法在后台呈现一些文本,并且我正在传递 (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading| NSStringDrawingTruncatesLastVisibleLine | NSLineBreakByWordWrapping)
作为选项。如果我的字符串长于两行(我已经为此计算了矩形的最大高度),我的文本将被截断 ...
.
效果很好,但是,我需要使用 ...more
进行截断(最后使用 "more"),而不是 ...
。
所有渲染都必须在后台线程上完成,因此任何 UI 组件都是不可能的。并且请不要推荐 TTTAttributedLabel
,因为我一开始就试图摆脱它,因为它导致我的应用程序滚动性能很差(已经尝试过了)。
在后台线程中绘制字符串时如何使用自定义截断标记?
可能不是最有效的方法,但我最终是这样的:
检查具有所需宽度且没有高度限制的字符串的大小(在 draw 方法中使用
MAXFLOAT
作为边界矩形的高度):NSStringDrawingOptions drawingOptions = (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading); [stringToDraw boundingRectWithSize:maximumSize options:drawingOptions context:nil].size;
我知道字体大小,检查结果大小的高度并检查它是否高于预定高度,这表明它是否超过两行。
如果超过两行,使用 [=17] 处答案的修改版本,获取
...more
大致开始的矩形点处的字符索引=](该点在原文矩形第二行右下角附近某处)://this string spans more than two lines. NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString]; NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; [textStorage addLayoutManager:layoutManager]; // init text container NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:size]; textContainer.lineFragmentPadding = 0; textContainer.maximumNumberOfLines = 2; textContainer.lineBreakMode = NSLineBreakByClipping; [layoutManager addTextContainer:textContainer]; CGPoint moreStartLocation = CGPointMake(size.width - 60, 30); //35 magic number NSUInteger characterIndex = [layoutManager characterIndexForPoint:moreStartLocation inTextContainer:textContainer fractionOfDistanceBetweenInsertionPoints:NULL]; stringToDraw = [attributedString attributedSubstringFromRange:NSMakeRange(0, characterIndex)].mutableCopy; [stringToDraw appendAttributedString:self.truncationText]; size = CGSizeMake(size.width, 35);
将原字符串截断为那里的字符(可选:也可以从limit中找到最后一个白色space(例如space,换行符)字符并得到子串从那时起避免剪字)。将“...更多”添加到原始字符串。 (文本可以是任何东西,具有任何属性。只要确保它能在两行中适合结果矩形。我已将其固定为 60px,但也可以获取所需截断字符串的大小,并使用其宽度精确找到最后一个字符)
照常渲染新字符串(以“...more”结尾):
UIGraphicsBeginImageContextWithOptions(contextSize, YES, 0); [stringToDraw drawWithRect:rectForDrawing options:drawingOptions context:nil]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
这个方法的好处是,因为我们没有接触 UIKit(UIGraphics...
函数和 UIImage
是 thread-safe)我们可以执行整个过程在后台 thread/queue。我正在使用它在背景中预渲染一些带有 attributes/links 等的文本内容,否则在滚动时会在 UI 线程中占用一两帧,并且效果很好。