我正在用 Core Text 制作杂志,并尝试自动在文本中添加连字符。我想我可以用这个功能做到这一点
CFStringGetHyphenationLocationBeforeIndex
但它不起作用,我在网上找不到任何例子。
我要做的是设置文本,如果我发现任何连字符位置,我会在此处放置一个“-”并通过访问器替换文本,以便它调用 setNeedsDisplay 并从头开始重新绘制。
- (void) setTexto:(NSAttributedString *)texto {
_texto = texto;
if (self.ctFrame != NULL) {
CFRelease(self.ctFrame);
self.ctFrame = NULL;
}
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextScaleCTM(context, 1.0, -1.0);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, self.bounds);
CTFramesetterRef ctFrameSetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(_texto));
self.ctFrame = CTFramesetterCreateFrame(ctFrameSetterRef, CFRangeMake(0, [_texto length]), path, NULL);
NSArray *lines = (__bridge NSArray *)(CTFrameGetLines(self.ctFrame));
CFIndex lineCount = [lines count];
NSLog(@"lines: %d", lines.count);
for(CFIndex idx = 0; idx < lineCount; idx++) {
CTLineRef line = CFArrayGetValueAtIndex((CFArrayRef)lines, idx);
CFRange lineStringRange = CTLineGetStringRange(line);
NSRange lineRange = NSMakeRange(lineStringRange.location, lineStringRange.length);
NSString* lineString = [self.texto.string substringWithRange:lineRange];
CFStringRef localeIdent = CFSTR("es_ES");
CFLocaleRef localeRef = CFLocaleCreate(kCFAllocatorDefault, localeIdent);
NSUInteger breakAt = CFStringGetHyphenationLocationBeforeIndex((__bridge CFStringRef)lineString, lineRange.length, CFRangeMake(0, lineRange.length), 0, localeRef, NULL);
if(breakAt!=-1) {
NSRange replaceRange = NSMakeRange(lineRange.location+breakAt, 0);
NSMutableAttributedString* attributedString = self.texto.mutableCopy;
[attributedString replaceCharactersInRange:replaceRange withAttributedString:[[NSAttributedString alloc] initWithString:@"-"]];
self.texto = attributedString.copy;
break;
} else {
CGFloat ascent;
CGFloat descent;
CTLineGetTypographicBounds(line, &ascent, &descent, nil);
CGContextSetTextPosition(context, 0.0, idx*-(ascent - 1 + descent)-ascent);
CTLineDraw(line, context);
}
}
}
问题是它第二次进入drawRect(带有新文本)lines.count log 为0。而且我不确定这是正确的方法。
也许还有另一种修改 CTLines 的方法(在上一行的“-”之后添加剩余的字符)。