如何使用正确的自动换行跨等边界视图拆分 NSAttributedString

How to split NSAttributedString across equal bounds views with correct word wrap

一段时间以来我一直在努力解决这个问题。有一些 API 可以为我们提供 NSAttributedString 的给定属性的边界大小。

但是没有直接的方法来获取适合给定范围的字符串范围。

我的要求是在几个分页视图中放置很长的字符串(PDF 不是一个选项,滚动也不是)。因此,我必须计算出每个视图的字符串大小(相同范围)。

经过研究,我发现 CTFramesetterSuggestFrameSizeWithConstraints 及其在 Core Text 中的朋友可能有所帮助。我尝试了 described here 方法,但结果范围有一个丑陋的问题:

它忽略断字(另一个与 Core Text 无关的问题,但我真的很想看看是否也有一些解决方案)。

基本上我想要跨 UITextView 个对象的文本分页,但没有得到正确的属性字符串拆分。

注意: 我的NSAttributedString属性如下:

let attributes: [NSAttributedString.Key : Any] = [.foregroundColor : textColor, .font : font, .paragraphStyle : titleParagraphStyle]

(titleParagraphStyle 已将 lineBreakMode 设置为 byWordWrapping)

extension UITextView
{
    func getStringSplits (fullString: String, attributes: [NSAttributedString.Key:Any]) -> [String]
    {
        let attributeString = NSAttributedString(string: fullString, attributes: attributes)
        let frameSetterRef = CTFramesetterCreateWithAttributedString(attributeString as CFAttributedString)

        var initFitRange:CFRange = CFRangeMake(0, 0)
        var finalRange:CFRange = CFRangeMake(0, fullString.count)

        var ranges: [Int] = []
        repeat
        {   
          CTFramesetterSuggestFrameSizeWithConstraints(frameSetterRef, initFitRange, attributes as CFDictionary, CGSize(width: bounds.size.width, height: bounds.size.height), &finalRange)
            initFitRange.location += finalRange.length
            ranges.append(finalRange.length)
        }
        while (finalRange.location < attributeString.string.count)

        var stringSplits: [String] = []

        var startIndex: String.Index = fullString.startIndex

        for n in ranges
        {
            let endIndex = fullString.index(startIndex, offsetBy: n, limitedBy: fullString.endIndex) ?? fullString.endIndex
            let theSubString = fullString[startIndex..<endIndex]
            stringSplits.append(String(theSubString))
            startIndex = endIndex
        }

        return stringSplits
    }
}

My requirement is to fit very long string across a few paged views (PDF is not an option, neither is scrolling). Hence I have to figure out string size for each view (same bounds).

不,你不必弄清楚。文本工具包堆栈将为您完成。

事实上,UITextView 会自动 将长文本从一个文本视图流动到另一个文本视图。这只是配置文本工具包堆栈的问题 — 一个具有多个文本容器的布局管理器。