Lol*_*z89 7 iphone objective-c ipad core-text ios
我试图动态创建基于长期NSAttributedString
分割成多个部分的书页.
我现在正在做的是使用此类别NSAttributedString
:
@interface NSAttributedString (Height)
- (CGFloat)boundingHeightForWidth:(CGFloat)inWidth;
@end
@implementation NSAttributedString (Height)
- (CGFloat)boundingHeightForWidth:(CGFloat)inWidth
{
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)self);
CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, CGSizeMake(inWidth, 10000), NULL);
CFRelease(framesetter);
return suggestedSize.height ;
}
@end
Run Code Online (Sandbox Code Playgroud)
由于我使用a绘制文本CTFramesetter
,因此工作正常并且正确返回了正确的框高度.不幸的是现在我需要逐行绘制文本:
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
// Flip the coordinate system
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
//CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
NSArray *lines = (__bridge NSArray *)(CTFrameGetLines(ctFrame));
CFIndex lineCount = [lines count];
for(CFIndex idx = 0; idx < lineCount; idx++)
{
// For each line found from where it starts and it's length
CTLineRef line = CFArrayGetValueAtIndex((CFArrayRef)lines, idx);
CFRange lineStringRange = CTLineGetStringRange(line);
NSRange lineRange = NSMakeRange(lineStringRange.location, lineStringRange.length);
// Get the line related string
NSString* lineString = [displayedString.string substringWithRange:lineRange];
// Calculate it's range
NSRange stringRange = NSMakeRange(lineStringRange.location, lineStringRange.length);
static const unichar softHypen = 0x00AD;
// Get the last char of the line
unichar lastChar = [lineString characterAtIndex:stringRange.length-1];
// Check if it's a soft hyphenation character
if(softHypen == lastChar) {
NSMutableAttributedString* lineAttrString = [[displayedString attributedSubstringFromRange:stringRange] mutableCopy];
NSRange replaceRange = NSMakeRange(stringRange.length-1, 1);
// Replace it with an hard hyphenation character
[lineAttrString replaceCharactersInRange:replaceRange withString:@"-"];
CTLineRef hyphenLine = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)lineAttrString);
CTLineRef justifiedLine = CTLineCreateJustifiedLine(hyphenLine, 1.0, self.frame.size.width);
CGFloat ascent;
CGFloat descent;
// Calculate the line height
CTLineGetTypographicBounds(justifiedLine, &ascent, &descent, NULL);
// Set the correct position for the line
CGContextSetTextPosition(context, 0.0, idx*-(ascent + descent)-ascent);
CTLineDraw(justifiedLine, context);
}
else{
CGFloat ascent;
CGFloat descent;
// Calculate the line height
CTLineGetTypographicBounds(line, &ascent, &descent, nil);
CGFloat y = idx*-(ascent + descent)-ascent;
// Set the correct position for the line
CGContextSetTextPosition(context, 0.0, y);
CTLineDraw(line, context);
}
}
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但并非总是如此.有时发生这种情况
如你所见,最后一行被切断了.有人有任何建议来解决这个烦人的问题吗?
由于某些原因,似乎(ascent + descent)
不是一条线的正确高度.事实上,上升器+ 1 +下降器等于点大小.
只需改变这个:
CGContextSetTextPosition(context, 0.0, idx*-(ascent + descent)-ascent);
Run Code Online (Sandbox Code Playgroud)
进入这个:
CGContextSetTextPosition(context, 0.0, idx*-(ascent - 1 + descent)-ascent);
Run Code Online (Sandbox Code Playgroud)
做了伎俩.参考:关于UIFont的Cocoanetics文章.感谢jverrijt的暗示!
归档时间: |
|
查看次数: |
3383 次 |
最近记录: |