Ios 如何使用正确的换行符在等边界视图中拆分NSAttributedString

Ios 如何使用正确的换行符在等边界视图中拆分NSAttributedString,ios,string,range,nsattributedstring,core-text,Ios,String,Range,Nsattributedstring,Core Text,我一直在努力解决这个问题。有一些API为我们提供了nsattributestring的给定属性的边界大小 但是,并没有直接的方法可以获得适合给定范围的字符串范围 我的要求是在几个页面视图中放入很长的字符串(PDF不是选项,滚动也不是)。因此,我必须计算每个视图的字符串大小(相同的边界) 经过研究,我发现,ctframesetter建议frameSizeWithConstraints及其核心文本中的朋友可能会有所帮助。我尝试了这种方法,但结果范围有一个丑陋的问题: 它忽略了分词(这是一个与核心文本

我一直在努力解决这个问题。有一些API为我们提供了
nsattributestring
的给定属性的边界大小

但是,并没有直接的方法可以获得适合给定范围的字符串范围

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

经过研究,我发现,
ctframesetter建议frameSizeWithConstraints
及其核心文本中的朋友可能会有所帮助。我尝试了这种方法,但结果范围有一个丑陋的问题:

它忽略了分词(这是一个与核心文本无关的不同问题,但我真的很想看看是否有解决方案)

基本上,我希望跨
UITextView
对象的数量对文本进行分页,但不希望得到正确的属性字符串拆分

注意: 我的
NSAttributedString
属性如下:

let attributes: [NSAttributedString.Key : Any] = [.foregroundColor : textColor, .font : font, .paragraphStyle : titleParagraphStyle]
titleParagraphStyle
已将
lineBreakMode
设置为
byWordWrapping

扩展UITextView { func getStringSplits(fullString:String,attributes:[NSAttributedString.Key:Any])->[String] { 让attributeString=NSAttributeString(string:fullString,attributes:attributes) 让frameSetterRef=CTFramesetterCreateWithAttributedString(attributeString作为CFAttributedString) var initFitRange:CFRange=CFRangeMake(0,0) var finalRange:CFRange=CFRangeMake(0,fullString.count) 变量范围:[Int]=[] 重复 { CTFramesetterSuggestFrameSizeWithConstraints(frameSetterRef、initFitRange、属性如CFDictionary、CGSize(宽度:bounds.size.width、高度:bounds.size.height)和finalRange) initFitRange.location+=finalRange.length ranges.append(finalRange.length) } while(finalRange.location 不,你不必弄明白。文本工具包堆栈会帮你完成的


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

+1谢谢。您知道它的任何示例链接吗?您的回答似乎表明我的方法有些过火。我缺少什么?案例1谢谢对于链接。我的问题实际上涉及任意数量的文本视图,具体取决于字符串长度。有没有一种方法可以根据文本范围创建任意数量的文本视图,并与您在链接中描述的共享相同的文本存储?我不知道有什么方法可以阻止它。听起来您正在编写一个读书应用程序,如Apple Books或Marv当然,这是一个解决得很好的问题。你的假设是正确的。问题是,我似乎无法将文本视图的创建与内容联系起来,也就是说,看看我的代码,它通过文本范围进行解析,为我提供适合每个页面的字符串数组。只是为了尝试,我遵循了你的2个文本视图的示例,但我看到空白的第2个文本视图,尽管它们共享相同的文本存储。
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
    }
}