0

我一直在寻找这个问题的答案,虽然这个话题有很多,但似乎没有什么能回答这个问题,至少对我来说不是。

我在情节提要中有一个固定大小的自定义 UIView(在原型单元中)。我为它继承了 UIView 并重写了 drawRect 方法。它基本上把一个格式化的字符串放在一起,然后我像这样绘制它:

// now for the actual drawing
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetShadowWithColor(context, 
                            CGSizeMake(0, 1), 
                            0,  
                            [UIColor whiteColor].CGColor);

CGMutablePathRef path = CGPathCreateMutable(); //1
CGPathAddRect(path, NULL, self.bounds );

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

CTFramesetterRef framesetter =
CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)stringToDraw); //3

CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);


CTFrameDraw(frame, context); //4

这很好并且有效,如果我将默认大小设置得足够大,它将处理多行文本。

CGPath 使用所有 UIView,这很好/想要的。

我想保持 CGPath 的宽度固定,但我希望高度扩展以容纳基本上无限量的文本,现在它只是被切断(由于路径/视图不够大以包含它)

我试过玩 CTFramesetterSuggestFrameSizeWithConstraints 无济于事。有人可以帮我开发一些可以实现我需要做的代码吗?

4

2 回答 2

0

知道要绘制的字符串和要使用的字体,您总是可以从中获取边界

CGSize boundingSize = CGSizeMake(self.bounds.size.width, CGFLOAT_MAX);
CGSize requiredSize = [yourText sizeWithFont:yourFont
                           constrainedToSize:boundingSize
                               lineBreakMode:UILineBreakModeWordWrap];
CGFloat requiredHeight = requiredSize.height;

你在那里得到了高度,并且可以在其他地方重复使用它......

于 2012-05-12T11:57:46.883 回答
0

这是您要尝试做的事情,请注意,这使用 CoreText API 并将返回正确的高度,这与错误的 sizeWithFont 答案不同。

// Measure the height required to display the attr string given a known width.
// This logic returns a height without an upper bound. Not thread safe!

- (NSUInteger) measureHeightForWidth:(NSUInteger)width
{
  NSAssert(self.isDoneAppendingText == TRUE, @"isDoneAppendingText");

  NSAssert(self.attrString, @"attrString");

  CFMutableAttributedStringRef attrString = self.attrString;
  CFRange stringRange = self.stringRange;

  CGFloat measuredHeight = 1.0f;

  // Create the framesetter with the attributed string.

  CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);

  if (framesetter) {
    CFRange fitRange;
    CGSize constraints = CGSizeMake(width, CGFLOAT_MAX); // width, height : CGFLOAT_MAX indicates unconstrained

    CGSize fontMeasureFrameSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, stringRange, (CFDictionaryRef)NULL, constraints, &fitRange);

    // Note that fitRange is ignored here, we only care about the measured height

    measuredHeight = fontMeasureFrameSize.height;

    CFRelease(framesetter);
  }

  return (NSUInteger) ceil(measuredHeight);
}
于 2013-06-29T19:40:15.350 回答