gpt4 book ai didi

iphone - NSString boundingRectWithSize 使用 CoreText Framesetter 切割高度短? iOS

转载 作者:可可西里 更新时间:2023-11-01 04:44:10 31 4
gpt4 key购买 nike

我有一个自定义的 UIView,它通过 CoreText 绘制一个 NSString:

- (NSMutableAttributedString *)getAttributedString : (NSString *)displayText {
string = [[NSMutableAttributedString alloc]
initWithString:displayText];

helvetica = CTFontCreateWithName(CFSTR("Helvetica"), 20.0, NULL);

[string addAttribute:(id)kCTFontAttributeName
value:(__bridge id)helvetica
range:NSMakeRange(0, [string length])];

return string;
}

- (void)drawRect:(CGRect)rect
{

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(
(__bridge CFAttributedStringRef)string);
// left column form
leftColumnPath = CGPathCreateMutable();
CGPathAddRect(leftColumnPath, NULL,
CGRectMake(0, 0,
self.bounds.size.width,
self.bounds.size.height));

// left column frame
textleftFrame = CTFramesetterCreateFrame(framesetter,
CFRangeMake(0, 0),
leftColumnPath, NULL);

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// right column form
rightColumnPath = CGPathCreateMutable();
CGPathAddRect(rightColumnPath, NULL,
CGRectMake(self.bounds.size.width/2.0, 0,
self.bounds.size.width/2.0,
self.bounds.size.height));

NSInteger rightColumStart = CTFrameGetVisibleStringRange(textleftFrame).length;

// right column frame
textrightFrame = CTFramesetterCreateFrame(framesetter,
CFRangeMake(rightColumStart, 0),
rightColumnPath,
NULL);
}

// flip the coordinate system
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

// draw
CTFrameDraw(textleftFrame, context);
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
CTFrameDraw(textrightFrame, context);
}

// cleanup
CFRelease(textleftFrame);
CGPathRelease(leftColumnPath);
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
CFRelease(textrightFrame);
CGPathRelease(rightColumnPath);
}
CFRelease(framesetter);
CFRelease(helvetica);
CFRelease(helveticaBold);
}

然后在另一个类中,我尝试使用 boundingRectWithSize 来计算 View 显示文本的时间长度(然后我设置了一个 UIScrollView 来匹配它):

NSMutableAttributedString * attributedString = [textView getAttributedString:text];

// Code here for iOS 7.0 - sizeWithFont is deprecated.
CGRect textBoxSize = [attributedString boundingRectWithSize:CGSizeMake(315.f, CGFLOAT_MAX) options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil];

textView.frame = CGRectMake(textView.frame.origin.x, pictureSpace, textBoxSize.size.width, textBoxSize.size.height);

getAttributedString 方法在上面。问题是 textView 的高度稍微太短,因此切断了文本的最后一行。任何人都可以提出什么问题吗?

此外,附带说明一下,为什么 boundingRectWithSize 中的大小必须为 315(即略短于屏幕宽度)而不是 320 才能正常工作?在 320 处,textView 对于屏幕来说有点太宽了。

编辑 - 这似乎只发生在某些字体上 - 例如 Verdana 工作正常。有没有知识渊博的人知道这是否与字形有关?

谢谢!

最佳答案

MMProgressHud项目中,不同组件的不同大小是使用 boundingRectWithSize:options:context: 方法计算的,我在使用 HelveticaNeue-Light 字体时遇到了一些问题,但没有人使用 Verdana字体。

我在 NSString 上创建了一个新类别,以使用 Core-Text 制作我自己的测量方法以具有常规行为。这是受此启发 post还有这个post .

#import "NSString+CustomMetrics.h"
#import<CoreText/CoreText.h>
@implementation NSString (CustomMetrics)

- (CGSize) boundingRectWithSize:(CGSize) bounds andFont:(UIFont*) uiFont
{

CTFontRef ctFont = CTFontCreateWithName((CFStringRef) uiFont.fontName,uiFont.pointSize, NULL);

CGFloat ascent = CTFontGetAscent(ctFont);
CGFloat descent = CTFontGetDescent(ctFont);
CGFloat leading = CTFontGetLeading(ctFont);

if (leading < 0)
leading = 0;

leading = floor (leading + 0.5);

CGFloat lineHeight = floor (ascent + 0.5) + floor (descent + 0.5) + leading;
CGFloat ascenderDelta = 0;
if (leading > 0)
ascenderDelta = 0;
else
ascenderDelta = floor (0.2 * lineHeight + 0.5);

CGFloat defaultLineHeight = lineHeight + ascenderDelta;

CTParagraphStyleSetting paragraphSettings[1] = { {kCTParagraphStyleSpecifierLineSpacingAdjustment, sizeof (CGFloat), &defaultLineHeight} };

CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(paragraphSettings, 1);
CFRange textRange = CFRangeMake(0, self.length);

// Create an empty mutable string big enough to hold our test
CFMutableAttributedStringRef string = CFAttributedStringCreateMutable(kCFAllocatorDefault, self.length);

// Inject our text into it
CFAttributedStringReplaceString(string, CFRangeMake(0, 0), (CFStringRef) self);

// Apply our font and line spacing attributes over the span
CFAttributedStringSetAttribute(string, textRange, kCTFontAttributeName, ctFont);
CFAttributedStringSetAttribute(string, textRange, kCTParagraphStyleAttributeName, paragraphStyle);

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(string);
CFRange fitRange;

CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, textRange, NULL, bounds, &fitRange);

CFRelease(framesetter);
CFRelease(string);
CFRelease(ctFont);

return frameSize;

}
@end

关于iphone - NSString boundingRectWithSize 使用 CoreText Framesetter 切割高度短? iOS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19076229/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com