获取UITextView中的行数,而不需要使用contentSize.height属性。

4
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我正在创建一个图像以在我的iOS应用程序中导出。我使用UIGraphicsBeginImageContext绘制图像的元素,但我一直在努力绘制UITextView。

首先,我创建了一个用于渲染的父视图:

var parentView : UIView = UIView(frame: CGRectMake(0, 0, 700, 700))

然后我通过编程创建textView并添加所有属性。我将其x = 100和y = 100以对齐图像中的文本。宽度= 500很好,每侧都有100px的边距:
var textView: UITextView = UITextView(frame: CGRectMake(100, 100, 500, 350))
textView.text = myText
textView.textContainerInset = UIEdgeInsetsMake(20, 20, 20, 20)
textView.backgroundColor = UIColor(red: 255, green: 255, blue: 255, alpha: 0.70)
textView.font = UIFont(name: "Helvetica Neue Light Italic", size: 35)

然后我将TextView在上下文中呈现,通过将其作为子视图添加到父视图中,然后获取要导出的图像:
parentView.addSubview(textView)        
parentView.layer.renderInContext(UIGraphicsGetCurrentContext())    
var newIMG = UIGraphicsGetImageFromCurrentImageContext()

问题是高度被固定为350px,但有时文本不足以使用所有区域。理想情况下,我想知道我的文本将使用多少行,这样我就可以给它一个比例高度,而不会有未使用的白色区域(请参见示例图片): Info 有什么想法可以以比例高度渲染文本视图吗?非常感谢!

你使用文本视图而不是标签的原因是什么? - Travis
不是很清楚,用UILabel可以实现吗? - Pablo Quemé
考虑到只有两行文本,使用UILabel会非常适合。如果您正在使用故事板(我强烈建议这样做),您可以更改约束和UILabel大小以完美地符合文本。只需记得将行数设置为2即可。 - Cole
你在这里看到的是保存在设备相册中的图像。这不是应用程序布局,我成功创建了一个良好的布局,但导出图片给我带来了这些问题! - Pablo Quemé
是的,可以(而且应该)使用UILabel来完成。UITextView用于处理输入,因此如果您只是使用先前输入的文本(或静态文本),则应使用UILabel。如果您希望标签中的文本居中,则将标签边界设置为区域的顶部和底部。如果您希望它位于顶部,则使用约束并为顶部设置==约束以及为底部设置>=约束。 - Travis
2个回答

26

我在苹果的文本布局编程指南中找到了解决这个问题的完美方法。苹果提供的解决方案是用Objective-C编写的,所以我进行了测试并将其改写为Swift。

这两种方法都运作良好,并返回UITextView中使用的确切行数,没有任何奇怪的数学计算,每次都100%准确。

以下是我为UITextView添加numberOfLines()方法的扩展:

extension UITextView {
    func numberOfLines() -> Int {
        let layoutManager = self.layoutManager
        let numberOfGlyphs = layoutManager.numberOfGlyphs
        var lineRange: NSRange = NSMakeRange(0, 1)
        var index = 0
        var numberOfLines = 0

        while index < numberOfGlyphs {
            layoutManager.lineFragmentRectForGlyphAtIndex(
                index, effectiveRange: &lineRange
            )
            index = NSMaxRange(lineRange)
            numberOfLines += 1
        }
        return numberOfLines
    }
}

直接在UITextView上执行此操作,如下所示:myTextView.numberOfLines() <- 返回一个整数


此扩展还可以轻松地转换为方法,如下所示:

func numberOfLines(textView: UITextView) -> Int {
    let layoutManager = textView.layoutManager
    let numberOfGlyphs = layoutManager.numberOfGlyphs
    var lineRange: NSRange = NSMakeRange(0, 1)
    var index = 0
    var numberOfLines = 0

    while index < numberOfGlyphs {
        layoutManager.lineFragmentRectForGlyphAtIndex(index, effectiveRange: &lineRange)
        index = NSMaxRange(lineRange)
        numberOfLines += 1
    }
    return numberOfLines
}

只需调用 numberOfLines(myTextView) 即可检索出行数的整数值


2
如果最后一个字符是 \n,则不会给出确切的行数。 - iHulk
遇到了相同的问题 ^^ - Alex Bollbach
是的,我也遇到了相同的问题,最后一个字符是 \n。 - Tram Nguyen

1

我没有找到获取行数的方法,但是我通过使用textView.sizeToFit()成功地去除了所有的空白。它很有效,希望有人会发现这个方法有用!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接