我有以下代码,我试图使用核心文本绘制,这就是为什么我不能像UILabel那样剪辑文本。换句话说,我必须找出省略号('...')我自己。
CGSize commentSize = [[self.sizeDictionary_ valueForKey:commentSizeKey] CGSizeValue];
CGSize actualSize = [[self.sizeDictionary_ valueForKey:actualCommentSizeKey] CGSizeValue];
NSString *actualComment = self.highlightItem_.comment;
if (actualSize.height > commentSize.height){
actualComment = [self.highlightItem_.comment stringByReplacingCharactersInRange:NSMakeRange(68, 3) withString:@"..."];
}
我很难找到基于CGSize的'...'的范围。解决这个问题的最佳方法是什么?
以下是我如何绘制它:
CFStringRef string = CFBridgingRetain(actualComment);
CFMutableAttributedStringRef comment = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
CFAttributedStringReplaceString (comment ,CFRangeMake(0, 0), string);
CGColorRef blue = CGColorRetain([UIColor colorWithRed:131/255.f green:204/255.f blue:253/255.f alpha:1.0].CGColor);
CGColorRef gray = CGColorRetain([UIColor colorWithWhite:165/255.f alpha:1.0].CGColor);
CFAttributedStringSetAttribute(comment, CFRangeMake(0, [name length]),kCTForegroundColorAttributeName, blue);
CFAttributedStringSetAttribute(comment, CFRangeMake([name length], [self.highlightItem_.comment length] - [name length]),kCTForegroundColorAttributeName, gray);
CGColorRelease (blue);
CGColorRelease (gray);
CTFontRef nameFont = CTFontCreateWithName(CFBridgingRetain(kProximaNovaBold), 13.0f, nil);
CFAttributedStringSetAttribute(comment,CFRangeMake(0, [name length]),kCTFontAttributeName,nameFont);
CTFontRef commentFont = CTFontCreateWithName(CFBridgingRetain(kProximaNovaRegular), 13.0f, nil);
CFAttributedStringSetAttribute(comment, CFRangeMake([name length], [self.highlightItem_.comment length] - [name length]),kCTFontAttributeName,commentFont);
CGFloat commentYOffset = floorf((self.commentHeight_ - commentSize.height)/2);
CGContextSaveGState(context);
CGRect captionFrame = CGRectMake(0, 0, rect.size.width - 80, commentSize.height);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(comment);
CGMutablePathRef captionFramePath = CGPathCreateMutable();
CGPathAddRect(captionFramePath, NULL, captionFrame);
CTFrameRef mainCaptionFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), captionFramePath, NULL);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, self.buttonSize_ + 25, self.imageHeight_ + self.commentHeight_ + 6 - commentYOffset);
CGContextScaleCTM(context, 1.0, -1.0);
CTFrameDraw(mainCaptionFrame, context);
CGContextRestoreGState(context);
答案 0 :(得分:5)
修改
(我在这里的原始答案没有用;它没有处理多行。如果有人想看到它的历史兴趣,请查看编辑历史。我删除了它,因为它会导致更多混乱比它解决了。目前的答案是正确的代码。)
你需要做的是让CTFramesetter
解决除最后一行之外的所有行。然后,如果需要,您可以手动截断最后一个。
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGRect pathRect = CGRectMake(50, 200, 200, 40);
CGPathRef path = CGPathCreateWithRect(pathRect, NULL);
CFAttributedStringRef attrString = (__bridge CFTypeRef)[self attributedString];
// Create the framesetter using the attributed string
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
// Create a single frame using the entire string (CFRange(0,0))
// that fits inside of path.
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
// Draw the lines except the last one
CFArrayRef lines = CTFrameGetLines(frame);
CFIndex lineCount = CFArrayGetCount(lines);
CGPoint origins[lineCount]; // I'm assuming that a stack variable is safe here.
// This would be bad if there were thousdands of lines, but that's unlikely.
CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), origins);
for (CFIndex i = 0; i < lineCount - 1; ++i) {
CGContextSetTextPosition(context, pathRect.origin.x + origins[i].x, pathRect.origin.y + origins[i].y);
CTLineDraw(CFArrayGetValueAtIndex(lines, i), context);
}
///
/// HERE'S THE INTERESTING PART
///
// Make a new last line that includes the rest of the string.
// The last line is already truncated (just with no truncation mark), so we can't truncate it again
CTLineRef lastLine = CFArrayGetValueAtIndex(lines, lineCount - 1);
CFIndex lastLocation = CTLineGetStringRange(lastLine).location;
CFRange restRange = CFRangeMake(lastLocation, CFAttributedStringGetLength(attrString) - lastLocation);
CFAttributedStringRef restOfString = CFAttributedStringCreateWithSubstring(NULL, attrString, restRange);
CTLineRef restLine = CTLineCreateWithAttributedString(restOfString);
// We need to provide the truncation mark. This is an ellipsis (Cmd-semicolon).
// You could also use "\u2026". Don't use dot-dot-dot. It'll work, it's just not correct.
// Obviously you could cache this…
CTLineRef ellipsis = CTLineCreateWithAttributedString((__bridge CFTypeRef)
[[NSAttributedString alloc] initWithString:@"…"]);
// OK, now let's truncate it and draw it. I'm being a little sloppy here. If ellipsis could possibly
// be wider than the path width, then this will fail and truncateLine will be NULL and we'll crash.
// Don't do that.
CTLineRef truncatedLine = CTLineCreateTruncatedLine(restLine,
CGRectGetWidth(pathRect),
kCTLineTruncationEnd,
ellipsis);
CGContextSetTextPosition(context, pathRect.origin.x + origins[lineCount - 1].x, pathRect.origin.y + origins[lineCount - 1].y);
CTLineDraw(truncatedLine, context);
CFRelease(truncatedLine);
CFRelease(ellipsis);
CFRelease(restLine);
CFRelease(restOfString);
CFRelease(frame);
CFRelease(framesetter);
CGPathRelease(path);
}
答案 1 :(得分:1)
这样的事情怎么样......
- (NSString *)truncate:(NSString *)string toWidth:(CGFloat)width withFont:(UIFont *)font {
CGSize size = [string sizeWithFont:font];
if (size.width <= width) return string;
NSString *truncatedString = [string copy];
NSString *ellipticalString = [truncatedString stringByAppendingString:@"..."];
size = [ellipticalString sizeWithFont:font];
while (size.width > width && truncatedString.length) {
truncatedString = [truncatedString substringToIndex:(truncatedString.length-1)];
ellipticalString = [truncatedString stringByAppendingString:@"..."];
size = [ellipticalString sizeWithFont:font];
}
return ellipticalString;
}
答案 2 :(得分:0)
最简单,最简单的方法,
NSString *theText = @"bla blah bla bhla bla bla";
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:NSLineBreakByTruncatingTail];
[theText drawInRect:dirtyRect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:style, NSParagraphStyleAttributeName,nil]];
for more