如何在Swift中用string初始化NSTextStorage

为了将另一个问题分解成更小的部分,我试图设置所有的TextKit组件。 但是,在改变我如何初始化NSTextStorage后,我正在崩溃。 出于testing目的,我已经简化了以下项目:

 import UIKit class ViewController3: UIViewController { @IBOutlet weak var textView: UITextView! @IBOutlet weak var myTextView: MyTextView! override func viewDidLoad() { super.viewDidLoad() let container = NSTextContainer(size: myTextView.bounds.size) let layoutManager = NSLayoutManager() let textStorage = NSTextStorage(string: "This is a test") layoutManager.addTextContainer(container) //layoutManager.textStorage = textView.textStorage // This works layoutManager.textStorage = textStorage // This doesn't work myTextView.layoutManager = layoutManager } } class MyTextView: UIView { var layoutManager: NSLayoutManager? override func drawRect(rect: CGRect) { let context = UIGraphicsGetCurrentContext(); // Enumerate all the line fragments in the text layoutManager?.enumerateLineFragmentsForGlyphRange(NSMakeRange(0, layoutManager!.numberOfGlyphs), usingBlock: { (lineRect: CGRect, usedRect: CGRect, textContainer: NSTextContainer!, glyphRange: NSRange, stop: UnsafeMutablePointer<ObjCBool>) -> Void in // Draw the line fragment self.layoutManager?.drawGlyphsForGlyphRange(glyphRange, atPoint: CGPointMake(0, 0)) }) } } 

它崩溃在enumerateLineFragmentsForGlyphRange EXC_I386_GPFLT的exception代码。 该代码不是很明确的解释。 最基本的问题似乎是我如何初始化NSTextStorage

如果我更换

 let textStorage = NSTextStorage(string: "This is a test") layoutManager.textStorage = textStorage 

有了这个

 layoutManager.textStorage = textView.textStorage 

那么它的工作。 我究竟做错了什么?

看来做事的方法是将NSLayoutManager添加到NSTextStorage对象(使用addLayoutManager :),而不是在布局pipe理器上设置textStorage属性。

从苹果的文件:

当您将NSLayoutManager添加到NSTextStorage对象时,将自动调用此方法; 你不需要直接调用它,但是你可能想要覆盖它。 如果要replace已build立的包含接收方的文本系统对象的NSTextStorage对象,请使用replaceTextStorage :.

链接到setTextStorage:NSLayoutManager

据推测,某些事情在'addLayoutManager:'中完成,这在setTextStorage中没有完成,导致崩溃。

如果一旦viewDidLoad完成,它可能会被清除,您可能还想增加textStoragevariables的范围。