gpt4 book ai didi

objective-c - 使用自定义字体计算 NSString 的高度

转载 作者:可可西里 更新时间:2023-11-01 04:53:55 25 4
gpt4 key购买 nike

我已经尝试解决这个问题一周了,我已经测试了很多想法,但我无法使用自定义正确计算 NSString 的大小字体。

我有一个包含文本的 UITextView 和一个 UIView,我在上面为 UITextView 中的行绘制行号。问题是 NSString UIKit Additions 在计算 NSString 的大小时忽略了制表符宽度。

在图片中可以清楚地看到第 7 行,该行在 UITextView 中呈现时换行,之后所有行都受到影响。

Simulator screenshot

我使用的字体是 Adobe Source Code Pro .

我已经尝试了 NSString UIKit 添加的所有方法,但都没有成功。

sizeWithFont

sizeWithFont:forWidth:lineBreakMode:

sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:

我还尝试用四个空格替换字符串中的所有制表符,这很有帮助,但仍然不能一直有效。对于某些行它有帮助,但对于某些行则没有。

关于如何正确计算 NSString 高度的任何建议? CoreText 也许吧?

一张小纸条。我也试图通过使用来自 UITextInput 协议(protocol)的几何 HitTest 方法来解决这个问题,当它们工作时,模拟器上的 cpu 负载是 100%,所以在真实设备上它会杀死应用程序,特别是如果我加载了大约 1500 多行代码的文件。

这是我用于 LineNumbersView.m 的代码要点.

最佳答案

假设 UITextView 和 Core Text 总是完全一致,那么后者绝对是一个解决方案,尽管它对于这个问题来说并不是非常简单。

你会:

  1. 在主视图中创建文本的属性字符串,在整个范围内设置适当的字体;
  2. 为属性字符串创建合适的 framesetter(使用 CTFramesetterCreateWithAttributedString );
  3. 创建一个 CGPath 描述字符串将被绘制到的绘图区域(作为 UIBezierPath 然后获取 CGPath 属性或通过创建一个和使用 CGPathAddRect );
  4. 因此从框架 setter 加上路径加上您感兴趣的字符串的子范围创建一个框架,这可能是所有的(参见 CTFramesetterCreateFrame);
  5. 然后您可以从框架中获取它将输出的各个行的 CFArray(使用 CTFrameGetLines ),尽管这些是屏幕排版行而不是您的源代码行;<
  6. 对于每一行,您可以获得它包含的原始字符串的范围(使用 CTLineGetStringRange ),从而允许您确定哪些在原始换行符之后立即开始,而不是由于自动换行;
  7. 您还可以获得 CGPoint 的 C 数组,其中每个代表屏幕上一行的原点 (CTFrameGetLineOrigins);通过使用您在 (6) 中学到的知识来查找位置,您可以获得相关线条的屏幕原点。

为了增加乐趣,Core Text 的像素输出在 OS X 和 iOS 上是相同的。然而 OS X 认为屏幕的原始位置是左下角,就像方格纸一样。 iOS 认为它在左上角,就像英文阅读顺序一样。措辞粗略的最终效果是在 iOS Core Text 上颠倒绘制。所以你需要考虑到这一点。在 iOS 术语中,您显然会看到第一行位于框架的最底部,第二行位于其上方的一行,等等。您需要翻转这些坐标。

即使您跳过了这么多环节,它最终也可能只有一百行左右的代码。

关于objective-c - 使用自定义字体计算 NSString 的高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13552027/

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