获取UITextView中没有contentSize.height的行数

Pab*_*emé 1 xcode image uitextview ios swift

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

首先,我创建一个父视图进行渲染:

var parentView : UIView = UIView(frame: CGRectMake(0, 0, 700, 700))
Run Code Online (Sandbox Code Playgroud)

然后我以编程方式创建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)
Run Code Online (Sandbox Code Playgroud)

然后我通过将它作为子视图添加到父视图中来渲染textview,然后我得到要导出的图像:

parentView.addSubview(textView)        
parentView.layer.renderInContext(UIGraphicsGetCurrentContext())    
var newIMG = UIGraphicsGetImageFromCurrentImageContext()
Run Code Online (Sandbox Code Playgroud)

问题是高度固定为350px,但有时文本不够长,无法使用所有区域.理想情况下,我想知道我的文本将使用多少行,所以我可以给它一个比例高度,而不是一个白色的未使用区域(例如参见图片):

信息 关于如何使用比例高度渲染文本视图的任何想法?非常感谢!

小智 13

我在Apple的Text Layout Programming Guide中找到了解决这个问题的完美解决方案.Apple提供的解决方案是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
    }
}
Run Code Online (Sandbox Code Playgroud)

只需在您的UITextView上直接调用它,就像这样:myTextView.numberOfLines()< - 返回一个Int


这个扩展也很容易转换为这样的方法:

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
}
Run Code Online (Sandbox Code Playgroud)

只需调用numberOfLines(myTextView)以检索行数的Int

  • 如果最后一个字符是\n,则不给出确切的行数 (2认同)