NSLayoutManager numberOfGlyphs 总是显示 0,Swift

NSLayoutManager numberOfGlyphs always showing 0, Swift

我正在尝试在每个页面上使用 UITextView 创建一个包含所需属性文本的多页 PDF。但是当应用程序被存档并通过 TestFlight 分发进行测试时,我遇到了问题。

下面是我用来生成多页的示例代码,

var textStorage = NSTextStorage()
textStorage = NSTextStorage(attributedString: attString)

let layoutManager = NSLayoutManager()

textStorage.addLayoutManager(layoutManager)

var pageSize = CGRect(x: 44, y: 108, width: 507, height: 690)
var lastGlyph = 0

while lastGlyph < layoutManager.numberOfGlyphs {
     let textContainer = NSTextContainer()
     let background = UINib(nibName: "background", bundle: nil).instantiate(withOwner: nil, options: nil)[0]
     background.frame = pageRect
     textContainer.size = subsequentPageSize.size
     layoutManager.addTextContainer(textContainer)
     let textView = UITextView(frame: pageSize, textContainer: textContainer)
     pageSize.origin.x += pageSize.width
     background.addSubview(textView)
     context.beginPage()
     background.layer.render(in: UIGraphicsGetCurrentContext()!)

     lastGlyph = NSMaxRange(layoutManager.glyphRange(for: textContainer))
}

如果 运行 在模拟器或设备上从 Xcode 构建时,这工作得很好,但一旦分发应用程序,layoutManager.numberOfGlyphs 总是 returns 0即使我打印()它显示的布局管理器,

    <NSLayoutManager: 0x7ff313c9f6d0>
    0 containers, text backing has 57 characters
    Currently holding 57 glyphs.
    Glyph tree contents:  57 characters, 57 glyphs, 1 nodes, 64 node bytes, 64 storage bytes, 128 total bytes, 2.25 bytes per character, 2.25 bytes per glyph
    Layout tree contents:  57 characters, 57 glyphs, 0 laid glyphs, 0 laid line fragments, 1 nodes, 64 node bytes, 0 storage bytes, 64 total bytes, 1.12 bytes per character, 1.12 bytes per glyph, 0.00 laid glyphs per laid line fragment, 0.00 bytes per laid line fragment'.

我是不是漏掉了一些愚蠢的东西,或者是否有我不知道的错误?我一辈子都无法理解为什么它不起作用!

感谢您提供的帮助。

我最终在 NSTextStorage 子类化注释中找到了解决方案,

The NSTextStorage class implements change management (via the beginEditing() and endEditing() methods), verification of attributes, delegate handling, and layout management notification. The one aspect it does not implement is managing the actual attributed string storage, which subclasses manage by overriding the two NSAttributedString primitives...

所以我更改了我的代码,并在整个序列的开头和结尾添加了 textStorage.beginEditing() 和 textStorage.endEditing(),如下所示,一旦项目实现,它现在就可以工作了从 Xcode.

直接构建到设备或模拟器
var textStorage = NSTextStorage()
textStorage.beginEditing()
if attribString != nil {
    textStorage = NSTextStorage(attributedString: attribString)
} else {
    textStorage = NSTextStorage(string: string)
}

let layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)

var pageSize = CGRect(x: 44, y: 108, width: 507, height: 690)
var lastGlyph = 0
while lastGlyph < layoutManager.numberOfGlyphs {     
    let textContainer = NSTextContainer()     
    let background = UINib(nibName: "background", bundle: nil).instantiate(withOwner: nil, options: nil)[0]     
    background.frame = pageRect     
    textContainer.size = subsequentPageSize.size     
    layoutManager.addTextContainer(textContainer)     
    let textView = UITextView(frame: pageSize, textContainer: textContainer)     
    background.addSubview(textView)     
    context.beginPage()     
    background.layer.render(in: UIGraphicsGetCurrentContext()!)    
    lastGlyph = NSMaxRange(layoutManager.glyphRange(for: textContainer))
}
textStorage.endEditing()