我需要创建一个包含一行文本的图像。但问题是,我首先需要创建上下文(CGBitmapContextCreate),要求图像的宽度和高度有可能以后计算文本的边界(通过CTLineGetImageBounds)。但我想要图像的大小=文本的边界:(我该怎么办?
实际上我使用
CGBitmapContextCreate
CTLineGetImageBounds
CTLineDraw
也许可以在没有上下文的情况下调用CTLineGetImageBounds?
注意:我在delphi上,这不是一个真正的问题,因为我可以访问所有API,我只需要函数名称
答案 0 :(得分:6)
您可以通过执行以下操作,根据要使用的字体计算NSString
占用的空间:
NSString *testString = @"A test string";
CGSize boundingSize = self.bounds.size;
CGRect labelRect = [testString
boundingRectWithSize:boundingSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{
NSFontAttributeName : [UIFont systemFontOfSize:14]
}
context:nil];
其中边界大小是您希望图像的最大大小。然后,您可以使用计算的大小来创建图像。
答案 1 :(得分:3)
有几种方法可以计算或多或少精确的边界框。您可以使用字体指标,迭代CTRun
或使用cocoa的字符串绘制API进行计算。
然而,我想提请你注意这个通常不可能的问题。虽然上述算法的结果在很多情况下已经足够,但有几种情况下它们是完全错误的:
您的算法可能不知道自定义文本属性。
文字可以包含"附件" (像图像,我认为表情符号也作为附件实现)。这些也必须考虑在内。
当我不得不解决这个问题时,我终于达到了以下解决方案:
CGImageCreateWithImageInRect
剪切生成的矩形。那个速度非常慢,但速度并不是我用例的优先考虑。
答案 2 :(得分:2)
好的,我找到了解决方案:使用CTLineGetImageBounds(aline,null {context});只需为上下文传递null,并按预期工作;)
答案 3 :(得分:2)
为了获得带有字体的文本大小,你需要编写。
let widthOfLabel = 400.0
let size = font?.sizeOfString(self.viewCenter.text!, constrainedToWidth: Double(widthOfLabel))
您必须使用以下字体扩展名才能获得带字体的文字大小。
extension UIFont {
func sizeOfString (string: String, constrainedToWidth width: Double) -> CGSize {
return NSString(string: string).boundingRectWithSize(CGSize(width: width, height: DBL_MAX),
options: NSStringDrawingOptions.UsesLineFragmentOrigin,
attributes: [NSFontAttributeName: self],
context: nil).size
}
}
答案 4 :(得分:1)
下面的代码用于根据字体计算NSString Size
extension UIFont {
func sizeOfString (string: String, constrainedToWidth width: Double) -> CGSize {
return NSString(string: string).boundingRectWithSize(CGSize(width: width, height: DBL_MAX),
options: NSStringDrawingOptions.UsesLineFragmentOrigin,
attributes: [NSFontAttributeName: self],
context: nil).size
}
}
OR 或者,您可以将其转换为NSString
if let ns_str:NSString = str as NSString? {
let sizeOfString = ns_str.boundingRectWithSize(
CGSizeMake(self.titleLabel.frame.size.width, CGFloat.infinity),
options: NSStringDrawingOptions.UsesLineFragmentOrigin,
attributes: [NSFontAttributeName: lbl.font],
context: nil).size
}
答案 5 :(得分:1)
听起来你已经完成了大部分工作。您只需要创建一个临时上下文来调用CTLineGetImageBounds
。我相信这个上下文非常小(例如,一个像素,甚至可能为零),当然你可以重复使用它。理想情况下,它应该具有与最终上下文相同的属性(除了大小),尽管在大多数情况下这甚至可能都不重要。它只需要元数据。