简体   繁体   English

如何在Swift中使用字符串初始化NSTextStorage

[英]How to Initialize NSTextStorage with a String in Swift

In order to break another problem down into smaller parts, I am trying to set up all the TextKit components. 为了将另一个问题分解成更小的部分,我试图设置所有的TextKit组件。 However, I am getting an crash after changing how I initialize NSTextStorage . 但是,在更改初始化NSTextStorage后,我遇到了崩溃。 For testing purposes I have simplified the project to the following: 出于测试目的,我已将项目简化为以下内容:

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))

        })
    }
}

It crashes at enumerateLineFragmentsForGlyphRange with an exception code of EXC_I386_GPFLT . 它在enumerateLineFragmentsForGlyphRange崩溃,异常代码为EXC_I386_GPFLT That code isn't very explanitory. 那段代码不是很解释。 The basic problem seems to be coming down to how I am initializing NSTextStorage . 基本问题似乎归结为我如何初始化NSTextStorage

If I replace 如果我更换

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

with this 有了这个

layoutManager.textStorage = textView.textStorage

then it works. 然后它工作。 What am I doing wrong? 我究竟做错了什么?

It seems the way to do things, is to add the NSLayoutManager to the NSTextStorage object, (using addLayoutManager:) rather than setting the textStorage property on the layout manager. 这似乎是做事的方法,是将NSLayoutManager添加到NSTextStorage对象,(使用addLayoutManager :)而不是在布局管理器上设置textStorage属性。

From Apple's documents: 来自Apple的文件:

This method is invoked automatically when you add an NSLayoutManager to an NSTextStorage object; 将NSLayoutManager添加到NSTextStorage对象时,将自动调用此方法; you should never need to invoke it directly, but you might want to override it. 你永远不需要直接调用它,但你可能想要覆盖它。 If you want to replace the NSTextStorage object for an established group of text-system objects containing the receiver, use replaceTextStorage:. 如果要为包含接收器的已建立的文本系统对象组替换NSTextStorage对象,请使用replaceTextStorage:。

Link to setTextStorage: for NSLayoutManager 链接到setTextStorage:用于NSLayoutManager

Presumably something gets done in 'addLayoutManager:' which doesn't get done in setTextStorage, causing the crash. 大概是在'addLayoutManager:'中完成了一些事情,这在setTextStorage中没有完成,导致崩溃。

You might also want to increase the scope of the textStorage variable, if it appears that it's getting cleared up once viewDidLoad finish. 您可能还希望增加textStorage变量的范围,如果它看起来在viewDidLoad完成后被清除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM